diff --git a/Demo/OpenQuant.API.chm b/Demo/OpenQuant.API.chm
new file mode 100644
index 0000000..b685158
Binary files /dev/null and b/Demo/OpenQuant.API.chm differ
diff --git a/Demo/OpenQuant.API.chw b/Demo/OpenQuant.API.chw
new file mode 100644
index 0000000..cdcc2db
Binary files /dev/null and b/Demo/OpenQuant.API.chw differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.obj b/Demo/QuantBox.OQ.Demo.CLI/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.obj
new file mode 100644
index 0000000..4cd0c8d
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.obj differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/AssemblyInfo.obj b/Demo/QuantBox.OQ.Demo.CLI/Debug/AssemblyInfo.obj
new file mode 100644
index 0000000..0bf6d91
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/AssemblyInfo.obj differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/CL.read.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/CL.read.1.tlog
new file mode 100644
index 0000000..0f6d88b
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/CL.read.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/CL.write.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/CL.write.1.tlog
new file mode 100644
index 0000000..43ed2ba
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/CL.write.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/QuantBox.OQ.Demo.CLI.lastbuildstate b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/QuantBox.OQ.Demo.CLI.lastbuildstate
new file mode 100644
index 0000000..74dd8b1
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/QuantBox.OQ.Demo.CLI.lastbuildstate
@@ -0,0 +1,2 @@
+#TargetFrameworkVersion=v4.5:PlatformToolSet=v120:EnableManagedIncrementalBuild=true:VCToolArchitecture=Native32Bit
+Debug|Win32|D:\用户目录\Documents\GitHub\OpenQuant\Demo\|
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/QuantBox.OQ.Demo.CLI.write.1u.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/QuantBox.OQ.Demo.CLI.write.1u.tlog
new file mode 100644
index 0000000..0fa69ab
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/QuantBox.OQ.Demo.CLI.write.1u.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/RSAENH.DLL.bi b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/RSAENH.DLL.bi
new file mode 100644
index 0000000..e69de29
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/TZRES.DLL.bi b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/TZRES.DLL.bi
new file mode 100644
index 0000000..e69de29
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/cl.command.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/cl.command.1.tlog
new file mode 100644
index 0000000..7c8f1b1
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/cl.command.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.command.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.command.1.tlog
new file mode 100644
index 0000000..4af348d
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.command.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.read.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.read.1.tlog
new file mode 100644
index 0000000..52024c1
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.read.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.write.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.write.1.tlog
new file mode 100644
index 0000000..a435195
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/link.write.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/metagen.read.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/metagen.read.1.tlog
new file mode 100644
index 0000000..46b134b
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/metagen.read.1.tlog
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/metagen.write.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/metagen.write.1.tlog
new file mode 100644
index 0000000..46b134b
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/metagen.write.1.tlog
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.command.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.command.1.tlog
new file mode 100644
index 0000000..bab415a
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.command.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.read.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.read.1.tlog
new file mode 100644
index 0000000..d7b4ca5
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.read.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.write.1.tlog b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.write.1.tlog
new file mode 100644
index 0000000..17dac71
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.12BB57A6.tlog/rc.write.1.tlog differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.Build.CppClean.log b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.Build.CppClean.log
new file mode 100644
index 0000000..d7a16bb
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.Build.CppClean.log
@@ -0,0 +1,41 @@
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.oq.demo.cli.pch
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\vc120.pdb
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\stdafx.obj
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.oq.demo.cli.obj
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\assemblyinfo.obj
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\.netframework,version=v4.5.assemblyattributes.obj
+c:\program files (x86)\smartquant ltd\openquant\bin\quantbox.oq.demo.cli.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\quantbox.oq.demo.cli.pdb
+c:\program files (x86)\smartquant ltd\openquant\bin\openquant.api.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.providers.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.instruments.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\openquant.objectmap.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.charting.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.series.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.execution.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.data.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.fix.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.quant.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\openquant.config.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.fixdata.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.file.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.services.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\sharpziplib.dll
+c:\program files (x86)\smartquant ltd\openquant\bin\smartquant.xml.dll
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\app.res
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.oq.demo.cli.vcxprojresolveassemblyreference.cache
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\cl.command.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\cl.read.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\cl.write.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\link.command.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\link.read.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\link.write.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\metagen.read.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\metagen.write.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\quantbox.oq.demo.cli.write.1u.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\rc.command.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\rc.read.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\rc.write.1.tlog
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\rsaenh.dll.bi
+d:\用户目录\documents\github\openquant\demo\quantbox.oq.demo.cli\debug\quantbox.12bb57a6.tlog\tzres.dll.bi
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.log b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.log
new file mode 100644
index 0000000..24bcd92
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.log
@@ -0,0 +1,28 @@
+生成启动时间为 2014/5/10 21:39:45。
+ 1>项目“D:\用户目录\Documents\GitHub\OpenQuant\Demo\QuantBox.OQ.Demo.CLI\QuantBox.OQ.Demo.CLI.vcxproj”在节点 2 上(Rebuild 个目标)。
+ 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(357,5): warning MSB8004: Output Directory does not end with a trailing slash. This build instance will add the slash as it is required to allow proper evaluation of the Output Directory.
+ 1>ClCompile:
+ D:\Program Files\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /AI"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\\" /AI"C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral" /AI"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\\" /Zi /clr /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _WINDLL /D _UNICODE /D UNICODE /EHa /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Yc"stdafx.h" /Fp"Debug\QuantBox.OQ.Demo.CLI.pch" /Fo"Debug\\" /Fd"Debug\vc120.pdb" /TP /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll" /FU"D:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\OpenQuant.API.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.dll" /analyze- /errorReport:prompt /clr:nostdlib Stdafx.cpp
+ Stdafx.cpp
+ D:\Program Files\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /AI"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\\" /AI"C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral" /AI"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\\" /Zi /clr /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _WINDLL /D _UNICODE /D UNICODE /EHa /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Yu"stdafx.h" /Fp"Debug\QuantBox.OQ.Demo.CLI.pch" /Fo"Debug\\" /Fd"Debug\vc120.pdb" /TP /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll" /FU"D:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\OpenQuant.API.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.dll" /analyze- /errorReport:prompt /clr:nostdlib AssemblyInfo.cpp QuantBox.OQ.Demo.CLI.cpp
+ AssemblyInfo.cpp
+ 1>AssemblyInfo.cpp(40): warning C4947: “RequestMinimum”: 标记为已过时
+ 消息: “Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.”
+ QuantBox.OQ.Demo.CLI.cpp
+ 正在生成代码...
+ D:\Program Files\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /Zi /clr /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _WINDLL /D _UNICODE /D UNICODE /EHa /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc120.pdb" /TP /analyze- /errorReport:prompt "C:\Users\Administrator\AppData\Local\Temp\.NETFramework,Version=v4.5.AssemblyAttributes.cpp"
+ .NETFramework,Version=v4.5.AssemblyAttributes.cpp
+ ResourceCompile:
+ C:\Program Files (x86)\Windows Kits\8.1\bin\x86\rc.exe /D _UNICODE /D UNICODE /l"0x0409" /nologo /fo"Debug\app.res" app.rc
+ Link:
+ D:\Program Files\Microsoft Visual Studio 12.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.OQ.Demo.CLI.dll" /INCREMENTAL /NOLOGO /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.OQ.Demo.CLI.pdb" /ASSEMBLYDEBUG /TLBID:1 /DYNAMICBASE /FIXED:NO /NXCOMPAT /MACHINE:X86 /DLL Debug\app.res
+ Debug\AssemblyInfo.obj
+ Debug\QuantBox.OQ.Demo.CLI.obj
+ Debug\Stdafx.obj
+ "Debug\.NETFramework,Version=v4.5.AssemblyAttributes.obj"
+ QuantBox.OQ.Demo.CLI.vcxproj -> C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.OQ.Demo.CLI.dll
+ 1>已完成生成项目“D:\用户目录\Documents\GitHub\OpenQuant\Demo\QuantBox.OQ.Demo.CLI\QuantBox.OQ.Demo.CLI.vcxproj”(Rebuild 个目标)的操作。
+
+生成成功。
+
+已用时间 00:00:09.16
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.vcxprojResolveAssemblyReference.cache b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.vcxprojResolveAssemblyReference.cache
new file mode 100644
index 0000000..3bdff4a
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/QuantBox.OQ.Demo.CLI.vcxprojResolveAssemblyReference.cache differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/Stdafx.obj b/Demo/QuantBox.OQ.Demo.CLI/Debug/Stdafx.obj
new file mode 100644
index 0000000..b020dc2
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/Stdafx.obj differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/app.res b/Demo/QuantBox.OQ.Demo.CLI/Debug/app.res
new file mode 100644
index 0000000..613b1c4
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/app.res differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/Debug/vc120.pdb b/Demo/QuantBox.OQ.Demo.CLI/Debug/vc120.pdb
new file mode 100644
index 0000000..b0ed333
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.CLI/Debug/vc120.pdb differ
diff --git a/Demo/QuantBox.OQ.Demo.CLI/QuantBox.OQ.Demo.CLI.vcxproj b/Demo/QuantBox.OQ.Demo.CLI/QuantBox.OQ.Demo.CLI.vcxproj
index e5fbae2..bea634c 100644
--- a/Demo/QuantBox.OQ.Demo.CLI/QuantBox.OQ.Demo.CLI.vcxproj
+++ b/Demo/QuantBox.OQ.Demo.CLI/QuantBox.OQ.Demo.CLI.vcxproj
@@ -43,7 +43,7 @@
true
- ..\..\..\..\..\..\Program Files %28x86%29\SmartQuant Ltd\OpenQuant\Bin
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin
false
diff --git a/Demo/QuantBox.OQ.Demo.v12.suo b/Demo/QuantBox.OQ.Demo.v12.suo
new file mode 100644
index 0000000..c943717
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo.v12.suo differ
diff --git a/Demo/QuantBox.OQ.Demo/Data/DataConvert_code.cs b/Demo/QuantBox.OQ.Demo/Data/DataConvert_code.cs
index aed2a22..88a6c90 100644
--- a/Demo/QuantBox.OQ.Demo/Data/DataConvert_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Data/DataConvert_code.cs
@@ -1,36 +1,36 @@
-using System;
-using System.Drawing;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-
-using QuantBox.CSharp2CTP;
-using QuantBox.Helper.CTP;
-
-namespace QuantBox.OQ.Demo.Data
-{
- public class DataConvert_code:Strategy
- {
- CThostFtdcDepthMarketDataField DepthMarketData;
-
- public override void OnTrade(Trade trade)
- {
- // 插件3.8.2.0 中开始可用,是将Trade数据中的深度数据取出
- if (DataConvert.TryConvert(trade, ref DepthMarketData))
- {
- Console.WriteLine("OnTrade " + DepthMarketData.LastPrice);
- Console.WriteLine("OnTrade " + DepthMarketData.UpperLimitPrice);
- }
- }
-
- public override void OnQuote(Quote quote)
- {
- // 插件3.8.2.1 中开始可用,是将Quote数据中的深度数据取出
- if (DataConvert.TryConvert(quote, ref DepthMarketData))
- {
- Console.WriteLine("OnQuote " + DepthMarketData.LastPrice);
- Console.WriteLine("OnQuote " + DepthMarketData.UpperLimitPrice);
- }
- }
- }
-}
+using System;
+using System.Drawing;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+
+using QuantBox.CSharp2CTP;
+using QuantBox.Helper.CTP;
+
+namespace QuantBox.OQ.Demo.Data
+{
+ public class DataConvert_code:Strategy
+ {
+ CThostFtdcDepthMarketDataField DepthMarketData;
+
+ public override void OnTrade(Trade trade)
+ {
+ // 插件3.8.2.0 中开始可用,是将Trade数据中的深度数据取出
+ if (DataConvert.TryConvert(trade, ref DepthMarketData))
+ {
+ Console.WriteLine("OnTrade " + DepthMarketData.LastPrice);
+ Console.WriteLine("OnTrade " + DepthMarketData.UpperLimitPrice);
+ }
+ }
+
+ public override void OnQuote(Quote quote)
+ {
+ // 插件3.8.2.1 中开始可用,是将Quote数据中的深度数据取出
+ if (DataConvert.TryConvert(quote, ref DepthMarketData))
+ {
+ Console.WriteLine("OnQuote " + DepthMarketData.LastPrice);
+ Console.WriteLine("OnQuote " + DepthMarketData.UpperLimitPrice);
+ }
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Data/DataMaker_code.cs b/Demo/QuantBox.OQ.Demo/Data/DataMaker_code.cs
index a626e46..6e5ee69 100644
--- a/Demo/QuantBox.OQ.Demo/Data/DataMaker_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Data/DataMaker_code.cs
@@ -1,101 +1,101 @@
-using System;
-using System.Drawing;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-
-namespace QuantBox.OQ.Demo.Data
-{
- ///
- /// 通过策略运行的方式来生成价差序列
- ///
- public class DataMaker_code : Strategy
- {
- static Instrument Instrument1;
- static Instrument Instrument2;
- Instrument Instrument3 = InstrumentManager.Instruments["IF1305 - IF1306"];
-
- long barSize;
-
- public override void OnStrategyStart()
- {
- if (Instrument1 == null)
- {
- Instrument1 = Instrument;
- }
- else if (Instrument2 == null)
- {
- Instrument2 = Instrument;
- }
-
- barSize = long.MaxValue;
- foreach (BarRequest barRequest in DataRequests.BarRequests)
- {
- barSize = Math.Min(barSize, barRequest.BarSize);
- }
- Console.WriteLine("barSize = {0}", barSize);
- }
-
- public override void OnStrategyStop()
- {
- Instrument1 = null;
- Instrument2 = null;
- }
-
- public override void OnTrade(Trade trade)
- {
- // 只用第二个合约的生成,数量约为第二个合约的Trade数
- // 假如第一个是IF1309,第二个是399300.SZ,这下生成的就6秒一次了
- // 按自己需求调
- if (Instrument == Instrument2)
- {
- if (Instrument1.Trade != null
- && Instrument2.Trade != null)
- {
- double Price = Instrument1.Trade.Price - Instrument2.Trade.Price;
- int Size = Math.Min(Instrument1.Trade.Size, Instrument2.Trade.Size);
- Trade t = new Trade(Clock.Now, Price, Size);
- DataManager.Add(Instrument3, t);
- }
- }
- }
-
- public override void OnQuote(Quote quote)
- {
- // 只要有报价就会生成,数量约为两个合约Quote之和
- //if(Instrument == Instrument2)
- {
- if (Instrument1.Quote != null
- && Instrument2.Quote != null)
- {
- double Ask = Instrument1.Quote.Ask - Instrument2.Quote.Bid;
- int AskSize = Math.Min(Instrument1.Quote.AskSize, Instrument2.Quote.BidSize);
- double Bid = Instrument1.Quote.Bid - Instrument2.Quote.Ask;
- int BidSize = Math.Min(Instrument1.Quote.BidSize, Instrument2.Quote.AskSize);
- Quote q = new Quote(Clock.Now, Bid, BidSize, Ask, AskSize);
- DataManager.Add(Instrument3, q);
- }
- }
- }
-
- public override void OnBarSlice(long size)
- {
- // 为了保证采样间隔一样,用户按自己的需求改
- if (size != barSize)
- {
- return;
- }
-
- // 如果添加了两个合约就会触发两次,只选后面一次保存
- if (Instrument == Instrument2)
- {
- // 本想保存成Bar,细想没必要,保存了Trade,用户自己手工压缩成Bar就成
- double Price = Instrument1.Bar.Close - Instrument2.Bar.Close;
- Trade t = new Trade(Clock.Now, Price, 0);
- // 注释了。在前面的OnTrade可以生成更细致的Trade
- //DataManager.Add(Instrument3,t);
- }
- }
- }
-
-}
+using System;
+using System.Drawing;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+
+namespace QuantBox.OQ.Demo.Data
+{
+ ///
+ /// 通过策略运行的方式来生成价差序列
+ ///
+ public class DataMaker_code : Strategy
+ {
+ static Instrument Instrument1;
+ static Instrument Instrument2;
+ Instrument Instrument3 = InstrumentManager.Instruments["IF1305 - IF1306"];
+
+ long barSize;
+
+ public override void OnStrategyStart()
+ {
+ if (Instrument1 == null)
+ {
+ Instrument1 = Instrument;
+ }
+ else if (Instrument2 == null)
+ {
+ Instrument2 = Instrument;
+ }
+
+ barSize = long.MaxValue;
+ foreach (BarRequest barRequest in DataRequests.BarRequests)
+ {
+ barSize = Math.Min(barSize, barRequest.BarSize);
+ }
+ Console.WriteLine("barSize = {0}", barSize);
+ }
+
+ public override void OnStrategyStop()
+ {
+ Instrument1 = null;
+ Instrument2 = null;
+ }
+
+ public override void OnTrade(Trade trade)
+ {
+ // 只用第二个合约的生成,数量约为第二个合约的Trade数
+ // 假如第一个是IF1309,第二个是399300.SZ,这下生成的就6秒一次了
+ // 按自己需求调
+ if (Instrument == Instrument2)
+ {
+ if (Instrument1.Trade != null
+ && Instrument2.Trade != null)
+ {
+ double Price = Instrument1.Trade.Price - Instrument2.Trade.Price;
+ int Size = Math.Min(Instrument1.Trade.Size, Instrument2.Trade.Size);
+ Trade t = new Trade(Clock.Now, Price, Size);
+ DataManager.Add(Instrument3, t);
+ }
+ }
+ }
+
+ public override void OnQuote(Quote quote)
+ {
+ // 只要有报价就会生成,数量约为两个合约Quote之和
+ //if(Instrument == Instrument2)
+ {
+ if (Instrument1.Quote != null
+ && Instrument2.Quote != null)
+ {
+ double Ask = Instrument1.Quote.Ask - Instrument2.Quote.Bid;
+ int AskSize = Math.Min(Instrument1.Quote.AskSize, Instrument2.Quote.BidSize);
+ double Bid = Instrument1.Quote.Bid - Instrument2.Quote.Ask;
+ int BidSize = Math.Min(Instrument1.Quote.BidSize, Instrument2.Quote.AskSize);
+ Quote q = new Quote(Clock.Now, Bid, BidSize, Ask, AskSize);
+ DataManager.Add(Instrument3, q);
+ }
+ }
+ }
+
+ public override void OnBarSlice(long size)
+ {
+ // 为了保证采样间隔一样,用户按自己的需求改
+ if (size != barSize)
+ {
+ return;
+ }
+
+ // 如果添加了两个合约就会触发两次,只选后面一次保存
+ if (Instrument == Instrument2)
+ {
+ // 本想保存成Bar,细想没必要,保存了Trade,用户自己手工压缩成Bar就成
+ double Price = Instrument1.Bar.Close - Instrument2.Bar.Close;
+ Trade t = new Trade(Clock.Now, Price, 0);
+ // 注释了。在前面的OnTrade可以生成更细致的Trade
+ //DataManager.Add(Instrument3,t);
+ }
+ }
+ }
+
+}
diff --git a/Demo/QuantBox.OQ.Demo/Data/DynamicBar_code.cs b/Demo/QuantBox.OQ.Demo/Data/DynamicBar_code.cs
index f74eb04..c6b90c6 100644
--- a/Demo/QuantBox.OQ.Demo/Data/DynamicBar_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Data/DynamicBar_code.cs
@@ -1,60 +1,60 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-namespace QuantBox.OQ.Demo.Data
-{
- ///
- /// 实时更新的Bar
- ///
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=118
- ///
- /// 注:貌似在OnQuote中直接引用Bar.High,Bar.Low,他会根据新的数据进行更新。
- ///
- public class DynamicBar_code:Strategy
- {
- double dbOpen = double.NaN;
- double dbHigh = double.MinValue;
- double dbLow = double.MaxValue;
- double dbClose = double.NaN;
- double dbVolume = 0;
-
- public override void OnTrade(Trade trade)
- {
- //每次在行情到来时更新最高、最低和成交量
- dbHigh = Math.Max(trade.Price, dbHigh);
- dbLow = Math.Min(trade.Price, dbLow);
- dbClose = trade.Price;
- dbVolume += trade.Size;
-
- //其他代码
- }
-
- public override void OnBarOpen(Bar bar)
- {
- //因为先OnTrade来后才OnBarOpen,
- //如果只在OnBarOpen中更新高低与量,
- //这时在OnTrade中计算的高低与量并不准确,
- //所以要提前到前一个Bar在OnBar时更新数据
- dbOpen = bar.Close;
- }
-
- public override void OnBar(Bar bar)
- {
- // 其他代码,用完后再重置
-
- // 重置
- if (180 == bar.Size)
- {
- dbHigh = double.MinValue;
- dbLow = double.MaxValue;
- dbVolume = 0;
- }
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+namespace QuantBox.OQ.Demo.Data
+{
+ ///
+ /// 实时更新的Bar
+ ///
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=118
+ ///
+ /// 注:貌似在OnQuote中直接引用Bar.High,Bar.Low,他会根据新的数据进行更新。
+ ///
+ public class DynamicBar_code:Strategy
+ {
+ double dbOpen = double.NaN;
+ double dbHigh = double.MinValue;
+ double dbLow = double.MaxValue;
+ double dbClose = double.NaN;
+ double dbVolume = 0;
+
+ public override void OnTrade(Trade trade)
+ {
+ //每次在行情到来时更新最高、最低和成交量
+ dbHigh = Math.Max(trade.Price, dbHigh);
+ dbLow = Math.Min(trade.Price, dbLow);
+ dbClose = trade.Price;
+ dbVolume += trade.Size;
+
+ //其他代码
+ }
+
+ public override void OnBarOpen(Bar bar)
+ {
+ //因为先OnTrade来后才OnBarOpen,
+ //如果只在OnBarOpen中更新高低与量,
+ //这时在OnTrade中计算的高低与量并不准确,
+ //所以要提前到前一个Bar在OnBar时更新数据
+ dbOpen = bar.Close;
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ // 其他代码,用完后再重置
+
+ // 重置
+ if (180 == bar.Size)
+ {
+ dbHigh = double.MinValue;
+ dbLow = double.MaxValue;
+ dbVolume = 0;
+ }
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Data/MyExtFilter_Scenario.cs b/Demo/QuantBox.OQ.Demo/Data/MyExtFilter_Scenario.cs
index 29142aa..fbfa667 100644
--- a/Demo/QuantBox.OQ.Demo/Data/MyExtFilter_Scenario.cs
+++ b/Demo/QuantBox.OQ.Demo/Data/MyExtFilter_Scenario.cs
@@ -1,75 +1,75 @@
-using System;
-using System.Collections.Generic;
-
-using OpenQuant.API;
-using OpenQuant.API.Engine;
-
-using QuantBox.OQ.Extensions;
-
-namespace QuantBox.OQ.Demo.Data
-{
- public class MyExtFilter_Scenario : Scenario
- {
- class MyExtFilter : ExtMarketDataFilter
- {
- Dictionary _trades = new Dictionary();
-
- MarketDataFilter filter;
-
- // 构造函数不能省
- public MyExtFilter(MarketDataProvider provider, MarketDataFilter filter)
- : base(provider)
- {
- this.filter = filter;
- }
-
- public override OpenQuant.API.Trade FilterTrade(OpenQuant.API.Trade trade, string symbol)
- {
- _trades[symbol] = trade;
-
- // 在这之前可以做自己的过滤
- Trade t = trade;
- if (filter != null)
- {
- t = filter.FilterTrade(trade, symbol);
- }
- if (t != null)
- {
- EmitTrade(symbol, Clock.Now, t.Price, t.Size);
- }
- else
- {
- return null;
- }
-
- Trade t1, t2;
-
- if ("IF1306-IF1307".Contains(symbol)
- || "IF1306-IF1307*2".Contains(symbol))
- {
- if (_trades.TryGetValue("IF1306", out t1)
- && _trades.TryGetValue("IF1307", out t2))
- {
- EmitTrade("IF1306-IF1307", Clock.Now, t1.Price - t2.Price, 0);
- EmitTrade("IF1306-IF1307*2", Clock.Now, t1.Price - t2.Price * 2.0, 0);
- }
- }
-
-
- // 注意,这个地方一定要返回null
- // 这实际上是让插件内部的Emit不调用
- return null;
- }
- }
-
-
- public override void Run()
- {
- MarketDataProvider.Filter = new MyExtFilter(MarketDataProvider,new MyFilter());
-
- Start();
- }
- }
-
-
-}
+using System;
+using System.Collections.Generic;
+
+using OpenQuant.API;
+using OpenQuant.API.Engine;
+
+using QuantBox.OQ.Extensions;
+
+namespace QuantBox.OQ.Demo.Data
+{
+ public class MyExtFilter_Scenario : Scenario
+ {
+ class MyExtFilter : ExtMarketDataFilter
+ {
+ Dictionary _trades = new Dictionary();
+
+ MarketDataFilter filter;
+
+ // 构造函数不能省
+ public MyExtFilter(MarketDataProvider provider, MarketDataFilter filter)
+ : base(provider)
+ {
+ this.filter = filter;
+ }
+
+ public override OpenQuant.API.Trade FilterTrade(OpenQuant.API.Trade trade, string symbol)
+ {
+ _trades[symbol] = trade;
+
+ // 在这之前可以做自己的过滤
+ Trade t = trade;
+ if (filter != null)
+ {
+ t = filter.FilterTrade(trade, symbol);
+ }
+ if (t != null)
+ {
+ EmitTrade(symbol, Clock.Now, t.Price, t.Size);
+ }
+ else
+ {
+ return null;
+ }
+
+ Trade t1, t2;
+
+ if ("IF1306-IF1307".Contains(symbol)
+ || "IF1306-IF1307*2".Contains(symbol))
+ {
+ if (_trades.TryGetValue("IF1306", out t1)
+ && _trades.TryGetValue("IF1307", out t2))
+ {
+ EmitTrade("IF1306-IF1307", Clock.Now, t1.Price - t2.Price, 0);
+ EmitTrade("IF1306-IF1307*2", Clock.Now, t1.Price - t2.Price * 2.0, 0);
+ }
+ }
+
+
+ // 注意,这个地方一定要返回null
+ // 这实际上是让插件内部的Emit不调用
+ return null;
+ }
+ }
+
+
+ public override void Run()
+ {
+ MarketDataProvider.Filter = new MyExtFilter(MarketDataProvider,new MyFilter());
+
+ Start();
+ }
+ }
+
+
+}
diff --git a/Demo/QuantBox.OQ.Demo/Data/MyFilter.cs b/Demo/QuantBox.OQ.Demo/Data/MyFilter.cs
index 93d1001..7be5f6c 100644
--- a/Demo/QuantBox.OQ.Demo/Data/MyFilter.cs
+++ b/Demo/QuantBox.OQ.Demo/Data/MyFilter.cs
@@ -1,124 +1,124 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Engine;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-using System.Collections.Generic;
-using QuantBox.OQ.Demo.Helper;
-
-namespace QuantBox.OQ.Demo.Data
-{
- public class MyFilter : MarketDataFilter
- {
- Dictionary goodTrades = new Dictionary();
- Dictionary TimeHelpers = new Dictionary();
-
- bool isRightTime(string symbol, DateTime datetime)
- {
- int nDatetime = datetime.Hour * 100 + datetime.Minute;
-
- TimeHelper th;
- if(!TimeHelpers.TryGetValue(symbol,out th))
- {
- th = new TimeHelper(symbol);
- TimeHelpers[symbol] = th;
- }
-
- return th.IsTradingTime(datetime);
- }
-
- public override Bar FilterBarOpen(Bar bar, string symbol)
- {
- // 只过滤Time Bar
- if (bar.Type != BarType.Time)
- return bar;
-
- // 日线数据不过滤
- if (bar.Size >= 86400)
- return bar;
-
- if (isRightTime(symbol, bar.DateTime))
- return bar;
-
- return null;
- }
-
- public override Bar FilterBar(Bar bar, string symbol)
- {
- if (bar.Type != BarType.Time)
- return bar;
-
- if (bar.Size >= 86400)
- return bar;
-
- // 注意!!!!!
- // 商品是13点30中中午开始,而如果你设置的是1小时一个Bar
- // 只使用DateTime进行判断会导致1点到2点的Bar被丢弃
- // 所以要多判断些条件
- if (isRightTime(symbol, bar.DateTime)
- || isRightTime(symbol, bar.EndTime)
- || isRightTime(symbol, bar.BeginTime))
- return bar;
-
- return null;
- }
-
- public override Trade FilterTrade(Trade trade, string symbol)
- {
- // 进行Trade过滤下面只给一个示例
- return trade;
-
- Trade lastGoodTrade = null;
-
- //检查数据表中是否有正常交易
- if (goodTrades.TryGetValue(symbol, out lastGoodTrade))
- {
- // 检查是否有数据特征
-
- //检查新的交易与上一个正常交易相比,价差是否在0.5%以上
- if (Math.Abs((1 - lastGoodTrade.Price / trade.Price) * 100) < 0.5)
- {
- //是正常交易,就更新为上一个正常交易
- goodTrades[symbol] = trade;
- return trade;
- }
- else
- {
- return null;
- }
- }
- else
- {
- // 将第一次交易数据作为初始正常数据
- goodTrades[symbol] = trade;
- // 将此数据添加到数据表里(第一个数据)
- return trade;
- }
- }
-
- public override Quote FilterQuote(OpenQuant.API.Quote quote, string symbol)
- {
- // 接收所有报价
- return quote;
- }
- }
-}
-
-/*
-注意:只能对一个Provider设置一个Filter,重复设置会覆盖
-
-1.在Scenario中使用
-MarketDataProvider.Filter = new MyFilter();
-
-2.在Script中使用
-MarketDataProvider provider = (MarketDataProvider)ProviderManager.Providers["CTP"];
-provider.Filter = new MyFilter();
-
-3.在Strategy中使用
-MarketDataProvider.Filter = new MyFilter();
-
- */
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Engine;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+using System.Collections.Generic;
+using QuantBox.OQ.Demo.Helper;
+
+namespace QuantBox.OQ.Demo.Data
+{
+ public class MyFilter : MarketDataFilter
+ {
+ Dictionary goodTrades = new Dictionary();
+ Dictionary TimeHelpers = new Dictionary();
+
+ bool isRightTime(string symbol, DateTime datetime)
+ {
+ int nDatetime = datetime.Hour * 100 + datetime.Minute;
+
+ TimeHelper th;
+ if(!TimeHelpers.TryGetValue(symbol,out th))
+ {
+ th = new TimeHelper(symbol);
+ TimeHelpers[symbol] = th;
+ }
+
+ return th.IsTradingTime(datetime);
+ }
+
+ public override Bar FilterBarOpen(Bar bar, string symbol)
+ {
+ // 只过滤Time Bar
+ if (bar.Type != BarType.Time)
+ return bar;
+
+ // 日线数据不过滤
+ if (bar.Size >= 86400)
+ return bar;
+
+ if (isRightTime(symbol, bar.DateTime))
+ return bar;
+
+ return null;
+ }
+
+ public override Bar FilterBar(Bar bar, string symbol)
+ {
+ if (bar.Type != BarType.Time)
+ return bar;
+
+ if (bar.Size >= 86400)
+ return bar;
+
+ // 注意!!!!!
+ // 商品是13点30中中午开始,而如果你设置的是1小时一个Bar
+ // 只使用DateTime进行判断会导致1点到2点的Bar被丢弃
+ // 所以要多判断些条件
+ if (isRightTime(symbol, bar.DateTime)
+ || isRightTime(symbol, bar.EndTime)
+ || isRightTime(symbol, bar.BeginTime))
+ return bar;
+
+ return null;
+ }
+
+ public override Trade FilterTrade(Trade trade, string symbol)
+ {
+ // 进行Trade过滤下面只给一个示例
+ return trade;
+
+ Trade lastGoodTrade = null;
+
+ //检查数据表中是否有正常交易
+ if (goodTrades.TryGetValue(symbol, out lastGoodTrade))
+ {
+ // 检查是否有数据特征
+
+ //检查新的交易与上一个正常交易相比,价差是否在0.5%以上
+ if (Math.Abs((1 - lastGoodTrade.Price / trade.Price) * 100) < 0.5)
+ {
+ //是正常交易,就更新为上一个正常交易
+ goodTrades[symbol] = trade;
+ return trade;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ // 将第一次交易数据作为初始正常数据
+ goodTrades[symbol] = trade;
+ // 将此数据添加到数据表里(第一个数据)
+ return trade;
+ }
+ }
+
+ public override Quote FilterQuote(OpenQuant.API.Quote quote, string symbol)
+ {
+ // 接收所有报价
+ return quote;
+ }
+ }
+}
+
+/*
+注意:只能对一个Provider设置一个Filter,重复设置会覆盖
+
+1.在Scenario中使用
+MarketDataProvider.Filter = new MyFilter();
+
+2.在Script中使用
+MarketDataProvider provider = (MarketDataProvider)ProviderManager.Providers["CTP"];
+provider.Filter = new MyFilter();
+
+3.在Strategy中使用
+MarketDataProvider.Filter = new MyFilter();
+
+ */
diff --git a/Demo/QuantBox.OQ.Demo/Data/Non-natural_TimeBar_code.cs b/Demo/QuantBox.OQ.Demo/Data/Non-natural_TimeBar_code.cs
index 680443c..fb4753a 100644
--- a/Demo/QuantBox.OQ.Demo/Data/Non-natural_TimeBar_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Data/Non-natural_TimeBar_code.cs
@@ -1,68 +1,68 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-namespace QuantBox.OQ.Demo.Data
-{
- ///
- /// 使用非自然时间的Bar
- /// 要
- ///
- /// 解决方案来源于英文官网
- /// http://www.smartquant.com/forums/viewtopic.php?f=64&t=7776
- ///
- public class Non_natural_TimeBar_code : Strategy
- {
- //临时Bar序列
- private BarSeries bars = null;
- private BarSeries bars30min = new BarSeries();
-
- /*
- 按照股指的时间要求,时间划分是这样的
- 9:15
- 9:45
- 10:15
- 10:45
- 11:15-11:30 13:00-13:15 两个15分钟被午休隔开了
- 13:45
- 14:15
- 14:45
- 15:15 交割日时只到15:00,已经到最后一天了,少15分钟也没什么
- */
- public override void OnBar(Bar bar)
- {
- //只处理15分钟的
- if (900 == bar.Size)
- {
- if (bars == null)
- bars = new BarSeries();
-
- bars.Add(bar);
-
- //在处理11:15-11:30 13:00-13:15这两个15分钟时会合并成一个
- if (bars.Count == 2) // 2 * 15min = 30 min
- {
- // get OHLC values for 30min bar
- double open = bars[0].Open;
- double high = bars.HighestHigh();
- double low = bars.LowestLow();
- double close = bars[1].Close;
- long volume = bars[0].Volume + bars[1].Volume;
-
- // todo something
- Bar b = new Bar(bars[0].DateTime, open, high, low, close, volume, 900 * 2);
- bars30min.Add(b);
- Console.WriteLine(b);
-
- // reset 15min bar series
- bars = null;
- }
- }
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+namespace QuantBox.OQ.Demo.Data
+{
+ ///
+ /// 使用非自然时间的Bar
+ /// 要
+ ///
+ /// 解决方案来源于英文官网
+ /// http://www.smartquant.com/forums/viewtopic.php?f=64&t=7776
+ ///
+ public class Non_natural_TimeBar_code : Strategy
+ {
+ //临时Bar序列
+ private BarSeries bars = null;
+ private BarSeries bars30min = new BarSeries();
+
+ /*
+ 按照股指的时间要求,时间划分是这样的
+ 9:15
+ 9:45
+ 10:15
+ 10:45
+ 11:15-11:30 13:00-13:15 两个15分钟被午休隔开了
+ 13:45
+ 14:15
+ 14:45
+ 15:15 交割日时只到15:00,已经到最后一天了,少15分钟也没什么
+ */
+ public override void OnBar(Bar bar)
+ {
+ //只处理15分钟的
+ if (900 == bar.Size)
+ {
+ if (bars == null)
+ bars = new BarSeries();
+
+ bars.Add(bar);
+
+ //在处理11:15-11:30 13:00-13:15这两个15分钟时会合并成一个
+ if (bars.Count == 2) // 2 * 15min = 30 min
+ {
+ // get OHLC values for 30min bar
+ double open = bars[0].Open;
+ double high = bars.HighestHigh();
+ double low = bars.LowestLow();
+ double close = bars[1].Close;
+ long volume = bars[0].Volume + bars[1].Volume;
+
+ // todo something
+ Bar b = new Bar(bars[0].DateTime, open, high, low, close, volume, 900 * 2);
+ bars30min.Add(b);
+ Console.WriteLine(b);
+
+ // reset 15min bar series
+ bars = null;
+ }
+ }
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Data/SaveData_code.cs b/Demo/QuantBox.OQ.Demo/Data/SaveData_code.cs
index 4daff57..c0b4fe3 100644
--- a/Demo/QuantBox.OQ.Demo/Data/SaveData_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Data/SaveData_code.cs
@@ -1,29 +1,29 @@
-using System;
-using System.Drawing;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-
-namespace QuantBox.OQ.Demo.Data
-{
- ///
- /// 使用策略来保存行情
- ///
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=24
- ///
- public class SaveData_code:Strategy
- {
- public override void OnTrade(Trade trade)
- {
- // 模拟行情时,不保存
- if (StrategyMode.Simulation != Mode)
- DataManager.Add(Instrument, trade);
- }
-
- public override void OnQuote(Quote quote)
- {
- if (StrategyMode.Simulation != Mode)
- DataManager.Add(Instrument, quote);
- }
- }
-}
+using System;
+using System.Drawing;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+
+namespace QuantBox.OQ.Demo.Data
+{
+ ///
+ /// 使用策略来保存行情
+ ///
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=24
+ ///
+ public class SaveData_code:Strategy
+ {
+ public override void OnTrade(Trade trade)
+ {
+ // 模拟行情时,不保存
+ if (StrategyMode.Simulation != Mode)
+ DataManager.Add(Instrument, trade);
+ }
+
+ public override void OnQuote(Quote quote)
+ {
+ if (StrategyMode.Simulation != Mode)
+ DataManager.Add(Instrument, quote);
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Helper/CloseTodayHelper.cs b/Demo/QuantBox.OQ.Demo/Helper/CloseTodayHelper.cs
index a8d5eda..7b901bf 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/CloseTodayHelper.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/CloseTodayHelper.cs
@@ -6,10 +6,19 @@
namespace QuantBox.OQ.Demo.Helper
{
+ ///
+ /// 平今仓助手,上交所有平令仓和平昨仓区别
+ ///
public class CloseTodayHelper
{
+ ///
+ /// 是否上交所
+ ///
public bool IsSHFE { get; private set; }
-
+ ///
+ /// 是否平今仓
+ ///
+ ///
public CloseTodayHelper(EnumExchangeID exchange)
{
this.IsSHFE = (exchange == EnumExchangeID.SHFE);
@@ -19,7 +28,11 @@ public CloseTodayHelper(bool IsSHFE)
{
this.IsSHFE = IsSHFE;
}
-
+ ///
+ /// 平今仓转换成平昨仓标志
+ ///
+ ///
+ ///
public EnumOpenClose Transform(EnumOpenClose OpenClose)
{
if (!IsSHFE)
@@ -29,22 +42,27 @@ public EnumOpenClose Transform(EnumOpenClose OpenClose)
}
return OpenClose;
}
-
+ ///
+ /// 计算平昨仓和平
+ ///
+ ///
+ ///
+ ///
public double GetCloseAndQty(PositionRecord pos,out EnumOpenClose OpenClose)
{
- double qty = 0;
- OpenClose = EnumOpenClose.CLOSE;
- if (IsSHFE)
+ double qty = 0;//可平仓量
+ OpenClose = EnumOpenClose.CLOSE;//开平标志,默认设置为平昨仓
+ if (IsSHFE)//是否上交所
{
- // 上海,先检查今仓
+ // 上海,先检查今仓可平量,今仓可平量=实际今仓量-挂平今量
qty = pos.QtyToday - pos.FrozenCloseToday;
- if (qty > 0)
+ if (qty > 0)//今仓可平量>0时
{
- OpenClose = EnumOpenClose.CLOSE_TODAY;
+ OpenClose = EnumOpenClose.CLOSE_TODAY;//设置平今标志
}
- else
+ else//今仓可平量==0时
{
- // 先算出昨仓,再查挂的昨平仓有多少
+ // 计算出昨可平仓量,再查挂的昨平仓有多少,昨仓=(实际持仓-实际今仓)-(挂平仓量 - 挂平今量)
qty = (pos.Qty - pos.QtyToday) - (pos.FrozenClose - pos.FrozenCloseToday);
}
}
diff --git a/Demo/QuantBox.OQ.Demo/Helper/CloseTodayHelper.cs.orig b/Demo/QuantBox.OQ.Demo/Helper/CloseTodayHelper.cs.orig
new file mode 100644
index 0000000..7b901bf
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo/Helper/CloseTodayHelper.cs.orig
@@ -0,0 +1,77 @@
+using QuantBox.OQ.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace QuantBox.OQ.Demo.Helper
+{
+ ///
+ /// 平今仓助手,上交所有平令仓和平昨仓区别
+ ///
+ public class CloseTodayHelper
+ {
+ ///
+ /// 是否上交所
+ ///
+ public bool IsSHFE { get; private set; }
+ ///
+ /// 是否平今仓
+ ///
+ ///
+ public CloseTodayHelper(EnumExchangeID exchange)
+ {
+ this.IsSHFE = (exchange == EnumExchangeID.SHFE);
+ }
+
+ public CloseTodayHelper(bool IsSHFE)
+ {
+ this.IsSHFE = IsSHFE;
+ }
+ ///
+ /// 平今仓转换成平昨仓标志
+ ///
+ ///
+ ///
+ public EnumOpenClose Transform(EnumOpenClose OpenClose)
+ {
+ if (!IsSHFE)
+ {
+ if (OpenClose == EnumOpenClose.CLOSE_TODAY)
+ return EnumOpenClose.CLOSE;
+ }
+ return OpenClose;
+ }
+ ///
+ /// 计算平昨仓和平
+ ///
+ ///
+ ///
+ ///
+ public double GetCloseAndQty(PositionRecord pos,out EnumOpenClose OpenClose)
+ {
+ double qty = 0;//可平仓量
+ OpenClose = EnumOpenClose.CLOSE;//开平标志,默认设置为平昨仓
+ if (IsSHFE)//是否上交所
+ {
+ // 上海,先检查今仓可平量,今仓可平量=实际今仓量-挂平今量
+ qty = pos.QtyToday - pos.FrozenCloseToday;
+ if (qty > 0)//今仓可平量>0时
+ {
+ OpenClose = EnumOpenClose.CLOSE_TODAY;//设置平今标志
+ }
+ else//今仓可平量==0时
+ {
+ // 计算出昨可平仓量,再查挂的昨平仓有多少,昨仓=(实际持仓-实际今仓)-(挂平仓量 - 挂平今量)
+ qty = (pos.Qty - pos.QtyToday) - (pos.FrozenClose - pos.FrozenCloseToday);
+ }
+ }
+ else
+ {
+ // 非上海,直接返回
+ qty = pos.Qty - pos.FrozenClose;
+ }
+ return qty;
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Helper/DualPosition.cs b/Demo/QuantBox.OQ.Demo/Helper/DualPosition.cs
index d133320..2ddad42 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/DualPosition.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/DualPosition.cs
@@ -18,14 +18,24 @@ namespace QuantBox.OQ.Demo.Helper
///
public class DualPosition
{
-
+ ///
+ /// //平今仓助手
+ ///
public CloseTodayHelper CloseTodayHelper;
+ ///
+ /// //多头仓位记录
+ ///
public PositionRecord Long = new PositionRecord();
+ ///
+ /// //空头仓位记录
+ ///
public PositionRecord Short = new PositionRecord();
public OrderBook_OneSide_Order Buy = new OrderBook_OneSide_Order(OrderSide.Buy);
public OrderBook_OneSide_Order Sell = new OrderBook_OneSide_Order(OrderSide.Sell);
-
+ ///
+ /// 订单的开平仓字典
+ ///
public Dictionary Order_OpenClose = new Dictionary();
public DualPosition(string symbol)
@@ -34,27 +44,37 @@ public DualPosition(string symbol)
}
public string Symbol { get; private set; }
-
+ ///
+ /// 多头持仓量
+ ///
public double LongQty
{
get { return Long.Qty; }
}
-
+ ///
+ /// 空头持仓量
+ ///
public double ShortQty
{
get { return Short.Qty; }
}
-
+ ///
+ /// 得到买入数量
+ ///
public double BidQty
{
get { return Buy.Size(); }
}
-
+ ///
+ /// 得到卖出数量
+ ///
public double AskQty
{
get { return Sell.Size(); }
}
-
+ ///
+ /// 得到买入价位文本信息
+ ///
public string BidString
{
get
@@ -65,7 +85,9 @@ public string BidString
Buy.PriceByIndex(0));
}
}
-
+ ///
+ /// 得到卖出价位文本信息
+ ///
public string AskString
{
get
@@ -89,16 +111,20 @@ public void ChangeTradingDay()
Buy.Clear();
Sell.Clear();
- Long.ChangeTradingDay();
- Short.ChangeTradingDay();
+ Long.ChangeTradingDay();//多头换日
+ Short.ChangeTradingDay();//空头换日
}
}
-
+ ///
+ /// 实际持仓
+ ///
public double NetQty
{
- get { return Long.Qty - Short.Qty; }
+ get { return Long.Qty - Short.Qty; }//多头仓 - 空头仓
}
-
+ ///
+ /// 是否等待
+ ///
public bool IsPending
{
get { return Buy.IsPending || Sell.IsPending; }
@@ -185,9 +211,9 @@ public void Filled(Order order)
{
lock (this)
{
- double LastQty = order.LastQty;
- double LastPrice = order.LastPrice;
- bool IsDone = order.IsDone;
+ double LastQty = order.LastQty;//得到最后的填充(部分填充)此订单的数量
+ double LastPrice = order.LastPrice;//得到最后的填充(部分填充)此订单价格
+ bool IsDone = order.IsDone;//返回true,如果这个订单最终状态(填充,拒绝或取消)
EnumOpenClose OpenClose = GetOpenClose(order);
@@ -322,22 +348,32 @@ public EnumOpenClose OrderCancelled(Order order)
return OpenClose;
}
}
-
+ ///
+ /// 得到订单的开平标志
+ ///
+ /// 订单
+ /// 返回值:开平仓标记
public EnumOpenClose GetOpenClose(Order order)
{
- EnumOpenClose OpenClose = EnumOpenClose.OPEN;
+ EnumOpenClose OpenClose = EnumOpenClose.OPEN;//开平仓标记
+ //得到指定order订单的开平仓标记,TryGetValue函数找到时则返回TURE,并返回指定的OpenClose开平仓标记
if(Order_OpenClose.TryGetValue(order, out OpenClose))
return OpenClose;
+ //没有找到则返回OPEN标记
return EnumOpenClose.OPEN;
}
-
+ ///
+ /// 订单被拒绝
+ ///
+ ///
+ ///
public EnumOpenClose OrderRejected(Order order)
{
lock (this)
{
- double LeavesQty = order.LeavesQty;
+ double LeavesQty = order.LeavesQty;//得到剩余的订单数量
- EnumOpenClose OpenClose = GetOpenClose(order);
+ EnumOpenClose OpenClose = GetOpenClose(order);//开平标记
switch (OpenClose)
{
diff --git a/Demo/QuantBox.OQ.Demo/Helper/GetBrokerInfoHelper.cs b/Demo/QuantBox.OQ.Demo/Helper/GetBrokerInfoHelper.cs
index 531cb39..5bfda93 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/GetBrokerInfoHelper.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/GetBrokerInfoHelper.cs
@@ -6,14 +6,21 @@
namespace QuantBox.OQ.Demo.Helper
{
+ ///
+ /// 获取代理商信息助手
+ ///
public class GetBrokerInfoHelper
{
- private const string PosiDirection = "PosiDirection";
- private const string Long = "Long";
- private const string PositionDate = "PositionDate";
- private const string Today = "Today";
- private const string Position = "Position";
-
+ private const string PosiDirection = "PosiDirection";//仓位方向
+ private const string Long = "Long";//
+ private const string PositionDate = "PositionDate";//仓位日期
+ private const string Today = "Today";//今仓
+ private const string Position = "Position";//仓位
+ ///
+ /// 转换
+ ///
+ ///
+ ///
public static void Transform(BrokerAccount brokerAccount,DualPosition dualPosition)
{
if (brokerAccount == null||dualPosition == null)
diff --git a/Demo/QuantBox.OQ.Demo/Helper/OpenCloseHelper.cs b/Demo/QuantBox.OQ.Demo/Helper/OpenCloseHelper.cs
index f8635df..d3a0615 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/OpenCloseHelper.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/OpenCloseHelper.cs
@@ -5,6 +5,9 @@
namespace QuantBox.OQ.Demo.Helper
{
+ ///
+ /// 开平仓助手
+ ///
public class OpenCloseHelper
{
public static EnumOpenClose CheckOpenClose(Order order)
diff --git a/Demo/QuantBox.OQ.Demo/Helper/OrderBook_BothSide_Size.cs b/Demo/QuantBox.OQ.Demo/Helper/OrderBook_BothSide_Size.cs
index b7bf624..bf16b56 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/OrderBook_BothSide_Size.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/OrderBook_BothSide_Size.cs
@@ -6,6 +6,9 @@
namespace QuantBox.OQ.Demo.Helper
{
+ ///
+ /// 双向挂单管理
+ ///
public class OrderBook_BothSide_Size
{
public OrderBook_OneSide_Size Sell = new OrderBook_OneSide_Size(OrderSide.Sell);
diff --git a/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Order.cs b/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Order.cs
index 7f2fece..2fb267b 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Order.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Order.cs
@@ -6,11 +6,26 @@
namespace QuantBox.OQ.Demo.Helper
{
+ ///
+ /// 挂单方向及动作
+ ///
public class OrderBook_OneSide_Order : IComparer, IComparer
{
+ ///
+ /// //订单方向(buy or sell)
+ ///
public OrderSide Side;
+ ///
+ /// 订单的排序列表的集合
+ ///
private SortedList> _Grid;
+ ///
+ /// //价格助手
+ ///
public PriceHelper PriceHelper;
+ ///
+ /// //撤单的散列集合
+ ///
private HashSet cancelList = new HashSet();
public IEnumerable>> GridList
@@ -34,12 +49,19 @@ public int Compare(int x, int y)
{
return x.CompareTo(y) * (Side == OrderSide.Buy ? -1 : 1);
}
-
+ ///
+ /// 比较两个订单的时间先后顺序
+ ///
+ ///
+ ///
+ ///
public int Compare(Order x, Order y)
{
return x.DateTime.CompareTo(y.DateTime);
}
-
+ ///
+ /// 订单数>0时,需要等待
+ ///
public bool IsPending
{
get { return _Grid.Count > 0; }
@@ -78,7 +100,10 @@ public void Add(Order order)
set.Add(order);
}
}
-
+ ///
+ /// 删除订单
+ ///
+ ///
public void Remove(Order order)
{
lock (this)
@@ -98,7 +123,11 @@ public void Remove(Order order)
}
}
}
-
+ ///
+ /// 到剩余的订单数量之和
+ ///
+ ///
+ ///
public double Size(SortedSet set)
{
//lock (this)
@@ -106,12 +135,15 @@ public double Size(SortedSet set)
double sum = 0;
foreach (var o in set)
{
- sum += o.LeavesQty;
+ sum += o.LeavesQty;//得到剩余的订单数量之和
}
return sum;
}
}
-
+ ///
+ /// 获取所有订单的
+ ///
+ ///
public double Size()
{
//lock (this)
@@ -136,7 +168,11 @@ public double SizeByIndex(int index)
return Size(set);
}
}
-
+ ///
+ ///
+ ///
+ ///
+ ///
public double SizeByLevel(int level)
{
//lock (this)
@@ -149,7 +185,11 @@ public double SizeByLevel(int level)
return Size(set);
}
}
-
+ ///
+ /// 获取价格水平,取TickSize整数倍
+ ///
+ ///
+ ///
public double SizeByPrice(double price)
{
lock (this)
@@ -158,7 +198,10 @@ public double SizeByPrice(double price)
return SizeByLevel(key);
}
}
-
+ ///
+ /// 撤单
+ ///
+ ///
public int Cancel()
{
lock (this)
@@ -171,25 +214,33 @@ public int Cancel()
return cnt;
}
}
-
+ ///
+ /// 撤消挂单
+ ///
+ /// 订单集合
+ /// 返回撤单数量
public int Cancel(SortedSet set)
{
lock (this)
{
- int cnt = 0;
- foreach (var o in set.ToList())
+ int cnt = 0;//撤单数量
+ foreach (var o in set.ToList())// 0 为推断类型变量,他的类型取决存储在set中的类型
{
- if (!o.IsDone)
+ if (!o.IsDone)//返回true,如果这个订单最终状态(填充,拒绝或取消)
{
- cancelList.Add(o);
- o.Cancel();
+ cancelList.Add(o);//撤单列表添加
+ o.Cancel();//取消此订单
++cnt;
}
}
return cnt;
}
}
-
+ ///
+ /// 撤消对应挂单
+ ///
+ ///
+ ///
public int CancelByIndex(int index)
{
lock (this)
@@ -227,7 +278,11 @@ public int CancelByIndex(int index)
// return cnt;
// }
//}
-
+ ///
+ /// 取消与price不同的
+ ///
+ ///
+ ///
public int CancelNotEqualPrice(double price)
{
lock (this)
@@ -261,7 +316,11 @@ public int CancelNotEqualPrice(double price)
// return cnt;
// }
//}
-
+ ///
+ /// 价格索引
+ ///
+ ///
+ ///
public double PriceByIndex(int index)
{
//lock (this)
@@ -273,19 +332,22 @@ public double PriceByIndex(int index)
return PriceHelper.GetPriceByLevel(key);
}
}
-
+ ///
+ /// 显示对应订单价格、剩余订单数量和
+ ///
+ ///
public override string ToString()
{
string str = "";
foreach (var i in _Grid)
{
- double price = PriceHelper.GetPriceByLevel(i.Key);
- double sum = 0;
+ double price = PriceHelper.GetPriceByLevel(i.Key);//获得订单价格
+ double sum = 0;//剩余的订单总数量
foreach (var o in i.Value)
{
- sum += o.LeavesQty;
+ sum += o.LeavesQty;//LeavesQty得到剩余的订单数量
}
- str += string.Format("{0} {1}{2}", price, sum, Environment.NewLine);
+ str += string.Format("{0} {1}{2}", price, sum, Environment.NewLine);//Environment.NewLine转换字符串
}
return str;
}
diff --git a/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Size.cs b/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Size.cs
index f39494a..f15f588 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Size.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/OrderBook_OneSide_Size.cs
@@ -6,6 +6,9 @@
namespace QuantBox.OQ.Demo.Helper
{
+ ///
+ /// 单向挂单管理
+ ///
public class OrderBook_OneSide_Size : IComparer
{
public OrderSide Side;
diff --git a/Demo/QuantBox.OQ.Demo/Helper/PositionRecord.cs b/Demo/QuantBox.OQ.Demo/Helper/PositionRecord.cs
index e8330d0..b5ceadd 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/PositionRecord.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/PositionRecord.cs
@@ -1,161 +1,200 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace QuantBox.OQ.Demo.Helper
-{
- ///
- /// 持仓量信息如何保存?
- /// 1.总持仓和今仓。使用此方式,这样在下单时对非上海的可以直接判断
- /// 2.昨持仓和今仓
- ///
- /// 1.上海与非上海都用一样的保存方法。使用此方式,统一
- /// 2.只上海分昨和今
- ///
- public class PositionRecord
- {
- ///
- /// 实际持仓
- ///
- public double Qty { get; set; }
- ///
- /// 实际持今仓量
- ///
- public double QtyToday { get; set; }
- ///
- /// 挂开仓量
- ///
- public double FrozenOpen { get; private set; }
- ///
- /// 挂平仓量
- ///
- public double FrozenClose { get; private set; }
- ///
- /// 挂平今量
- ///
- public double FrozenCloseToday { get; private set; }
- ///
- /// 开仓手数累计
- ///
- public double CumOpenQty { get; private set; }
- ///
- /// 撤单次数累计,注意,不区分主动撤单与被动撤单
- ///
- public double CumCancelCnt { get; set; }
- ///
- /// 持仓成本
- ///
- public double HoldingCost { get; private set; }
-
-
- public void Reset()
- {
- Qty = 0;
- HoldingCost = 0;
-
- ChangeTradingDay();
- }
-
- public void ChangeTradingDay()
- {
- QtyToday = 0;
- FrozenOpen = 0;
- FrozenClose = 0;
- FrozenCloseToday = 0;
- CumOpenQty = 0;
- CumCancelCnt = 0;
- }
-
- ///
- /// 持仓平均成本
- ///
- public double AvgPrice
- {
- get
- {
- if (Qty == 0)
- return 0;
- else
- return HoldingCost / Qty;
- }
- }
-
- public override string ToString()
- {
- return string.Format("持仓量:{0},挂开仓量:{1},挂平仓量:{2},开仓手数累计:{3}",
- Qty, FrozenOpen, FrozenClose, CumOpenQty);
- }
-
- public void NewOrderOpen(double Qty)
- {
- FrozenClose += Qty;
- }
-
- public void NewOrderClose(double Qty)
- {
- FrozenClose += Qty;
- }
-
- public void NewOrderCloseToday(double Qty)
- {
- FrozenCloseToday += Qty;
- FrozenClose += Qty;
- }
-
- public void FilledOpen(double LastQty, double LastPrice)
- {
- Qty += LastQty;
- QtyToday += LastQty;
- FrozenOpen -= LastQty;
- CumOpenQty += LastQty;
- HoldingCost += LastPrice * LastQty;
- }
-
- public void FilledClose(double LastQty, double LastPrice)
- {
- Qty -= LastQty;
- FrozenClose -= LastQty;
- if (Qty == 0)
- {
- HoldingCost = 0;
- }
- else
- {
- HoldingCost -= LastPrice * LastQty;
- }
- }
-
- public void FilledCloseToday(double LastQty, double LastPrice)
- {
- Qty -= LastQty;
- QtyToday -= LastQty;
- FrozenClose -= LastQty;
- FrozenCloseToday -= LastQty;
- if (Qty == 0)
- {
- HoldingCost = 0;
- }
- else
- {
- HoldingCost -= LastPrice * LastQty;
- }
- }
-
- public void OrderRejectedOpen(double LeavesQty)
- {
- FrozenOpen -= LeavesQty;
- }
-
- public void OrderRejectedClose(double LeavesQty)
- {
- FrozenClose -= LeavesQty;
- }
-
- public void OrderRejectedCloseToday(double LeavesQty)
- {
- FrozenCloseToday -= LeavesQty;
- FrozenClose -= LeavesQty;
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace QuantBox.OQ.Demo.Helper
+{
+ ///
+ /// 持仓量信息如何保存?
+ /// 1.总持仓和今仓。使用此方式,这样在下单时对非上海的可以直接判断
+ /// 2.昨持仓和今仓
+ ///
+ /// 1.上海与非上海都用一样的保存方法。使用此方式,统一
+ /// 2.只上海分昨和今
+ ///
+ public class PositionRecord
+ {
+ ///
+ /// 实际持仓
+ ///
+ public double Qty { get; set; }
+ ///
+ /// 实际持今仓量
+ ///
+ public double QtyToday { get; set; }
+ ///
+ /// 挂开仓量
+ ///
+ public double FrozenOpen { get; private set; }
+ ///
+ /// 挂平仓量
+ ///
+ public double FrozenClose { get; private set; }
+ ///
+ /// 挂平今量
+ ///
+ public double FrozenCloseToday { get; private set; }
+ ///
+ /// 开仓手数累计
+ ///
+ public double CumOpenQty { get; private set; }
+ ///
+ /// 撤单次数累计,注意,不区分主动撤单与被动撤单
+ ///
+ public double CumCancelCnt { get; set; }
+ ///
+ /// 持仓成本
+ ///
+ public double HoldingCost { get; private set; }
+
+ ///
+ /// 重新初始化
+ ///
+ public void Reset()
+ {
+ Qty = 0;//实际持仓量
+ HoldingCost = 0;//持仓成本
+
+ ChangeTradingDay();
+ }
+
+ ///
+ /// 换日,用户自己要记得挂单要撤
+ ///
+ public void ChangeTradingDay()
+ {
+ QtyToday = 0;//今实际持仓量=0
+ FrozenOpen = 0;//挂开仓量=0
+ FrozenClose = 0;//挂平仓量=0
+ FrozenCloseToday = 0;//挂平今量=0
+ CumOpenQty = 0;//开仓手数累计=0
+ CumCancelCnt = 0;//撤单次数累计=0
+ }
+
+ ///
+ /// 持仓平均成本
+ ///
+ public double AvgPrice
+ {
+ get
+ {
+ if (Qty == 0)
+ return 0;
+ else
+ return HoldingCost / Qty;//持仓成本/持仓量
+ }
+ }
+ ///
+ /// 转换持仓量信息为文本信息
+ ///
+ ///
+ public override string ToString()
+ {
+ return string.Format("持仓量:{0},挂开仓量:{1},挂平仓量:{2},开仓手数累计:{3}",
+ Qty, FrozenOpen, FrozenClose, CumOpenQty);
+ }
+ ///
+ /// 新增开仓订单
+ ///
+ /// 开仓数量
+ public void NewOrderOpen(double Qty)
+ {
+ FrozenClose += Qty;//挂平仓量+开仓手数
+ }
+ ///
+ /// 新增平仓订单
+ ///
+ /// 平仓数量
+ public void NewOrderClose(double Qty)
+ {
+ FrozenClose += Qty;//挂平仓量+开仓手数
+ }
+ ///
+ /// 新增平今订单
+ ///
+ /// 平今数量
+ public void NewOrderCloseToday(double Qty)
+ {
+ FrozenCloseToday += Qty;//挂平今数量变动
+ FrozenClose += Qty;//挂平仓量变动
+ }
+ ///
+ /// 填充开仓
+ ///
+ ///
+ ///
+ public void FilledOpen(double LastQty, double LastPrice)
+ {
+ Qty += LastQty;
+ QtyToday += LastQty;
+ FrozenOpen -= LastQty;
+ CumOpenQty += LastQty;
+ HoldingCost += LastPrice * LastQty;
+ }
+ ///
+ /// 填充平仓
+ ///
+ ///
+ ///
+ public void FilledClose(double LastQty, double LastPrice)
+ {
+ Qty -= LastQty;
+ FrozenClose -= LastQty;
+ if (Qty == 0)
+ {
+ HoldingCost = 0;
+ }
+ else
+ {
+ HoldingCost -= LastPrice * LastQty;
+ }
+ }
+ ///
+ /// 填充平今仓
+ ///
+ ///
+ ///
+ public void FilledCloseToday(double LastQty, double LastPrice)
+ {
+ Qty -= LastQty;// 实际持仓量 - 平今仓订单的数量
+ QtyToday -= LastQty;//实际持今仓量 - 平今仓订单的数量
+ FrozenClose -= LastQty;//挂平仓量 - 平今仓订单的数量
+ FrozenCloseToday -= LastQty;//挂平今量 - 平今仓订单的数量
+ //重新计算持仓成本
+ if (Qty == 0)
+ {
+ HoldingCost = 0;
+ }
+ else
+ {
+ HoldingCost -= LastPrice * LastQty;//减去平仓的成本
+ }
+ }
+ ///
+ /// 拒绝订单开仓
+ ///
+ ///
+ public void OrderRejectedOpen(double LeavesQty)
+ {
+ FrozenOpen -= LeavesQty;
+ }
+ ///
+ /// 拒绝订单平仓
+ ///
+ ///
+ public void OrderRejectedClose(double LeavesQty)
+ {
+ FrozenClose -= LeavesQty;
+ }
+ ///
+ /// 拒绝订单平今仓
+ ///
+ ///
+ public void OrderRejectedCloseToday(double LeavesQty)
+ {
+ FrozenCloseToday -= LeavesQty;
+ FrozenClose -= LeavesQty;
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Helper/PriceHelper.cs b/Demo/QuantBox.OQ.Demo/Helper/PriceHelper.cs
index cac1b23..7a1c2d6 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/PriceHelper.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/PriceHelper.cs
@@ -6,10 +6,22 @@
namespace QuantBox.OQ.Demo.Helper
{
+ ///
+ /// 价格助手
+ ///
public class PriceHelper
{
+ ///
+ /// 价格上限
+ ///
public double UpperLimitPrice { get; private set; }
+ ///
+ /// 价格下限
+ ///
public double LowerLimitPrice { get; private set; }
+ ///
+ /// Tick最小变量数量
+ ///
public double TickSize { get; private set; }
public PriceHelper(double TickSize)
@@ -27,7 +39,12 @@ public PriceHelper(double UpperLimitPrice,
this.LowerLimitPrice = LowerLimitPrice;
this.TickSize = TickSize;
}
-
+ ///
+ /// 获取价格水平,取TickSize的整数倍
+ ///
+ /// 价格
+ /// 买卖方向
+ /// 价格
public int GetLevelByPrice(double price, OrderSide Side)
{
price = Math.Min(price, UpperLimitPrice);
@@ -36,17 +53,31 @@ public int GetLevelByPrice(double price, OrderSide Side)
int index = (int)((Side == OrderSide.Buy) ? Math.Ceiling(price / TickSize) : Math.Floor(price / TickSize));
return index;
}
-
+ ///
+ /// 获得价格
+ ///
+ /// 价格
+ ///
public double GetPriceByLevel(int level)
{
- return level * TickSize;
+ return level * TickSize;//TickSize为每一跳的价格
}
-
+ ///
+ /// 修正价格水平
+ ///
+ ///
+ ///
+ ///
public double FixPrice(double price, OrderSide Side)
{
return GetPriceByLevel(GetLevelByPrice(price, Side));
}
-
+ ///
+ /// 获得匹配的价格
+ ///
+ ///
+ ///
+ ///
public double GetMatchPrice(Strategy strategy, OrderSide side)
{
Quote quote = strategy.Quote;
diff --git a/Demo/QuantBox.OQ.Demo/Helper/TimeHelper.cs b/Demo/QuantBox.OQ.Demo/Helper/TimeHelper.cs
index 871af99..ca02876 100644
--- a/Demo/QuantBox.OQ.Demo/Helper/TimeHelper.cs
+++ b/Demo/QuantBox.OQ.Demo/Helper/TimeHelper.cs
@@ -13,11 +13,22 @@ public enum EnumTradingTime
COMMODITY_0230, // 黄金、白银
COMMODITY_0100,
}
-
+ ///
+ /// 时间助手
+ ///
public class TimeHelper
{
+ ///
+ /// 交易时间
+ ///
public int[] WorkingTime;
+ ///
+ /// 结束时间
+ ///
public int EndOfDay { get; private set; }
+ ///
+ /// 开始时间
+ ///
public int BeginOfDay { get; private set; }
public int[] WorkingTime_Financial = { 915, 1130, 1300, 1515 }; //IF,TF,IO
@@ -25,14 +36,17 @@ public class TimeHelper
public int[] WorkingTime_Commodity_0230 = { 0, 230, 900, 1015, 1030, 1130, 1330, 1500, 2100, 2400 };//au,ag
public int[] WorkingTime_Commodity_0100 = { 0, 100, 900, 1015, 1030, 1130, 1330, 1500, 2100, 2400 };//铜、铝、铅、锌
- private int EndOfDay_Financial = 1515; //IF
- private int EndOfDay_Commodity = 1500; //商品
+ private int EndOfDay_Financial = 1515; //IF 结束时间
+ private int EndOfDay_Commodity = 1500; //商品结束时间
- private int BeginOfDay_Financial = 915;
- private int BeginOfDay_Commodity = 900;
+ private int BeginOfDay_Financial = 915;//上期所的开始时间
+ private int BeginOfDay_Commodity = 900;//商品的开始时间
private int BeginOfDay_Commodity_0230 = 2100;
private int BeginOfDay_Commodity_0100 = 2100;
-
+ ///
+ /// 确定开收盘时间
+ /// 构造函数,根据合约属性确定开盘、收盘和交易时间
+ ///
public TimeHelper(EnumTradingTime tt)
{
switch(tt)
@@ -59,21 +73,32 @@ public TimeHelper(EnumTradingTime tt)
break;
}
}
-
+ ///
+ /// 构造函数:根据合约ID确定开盘、收盘、交易时间
+ ///
+ ///
public TimeHelper(string instrument):this(GetTradingTime(instrument))
{
}
-
+ ///
+ ///
+ ///
+ /// 开始时间
+ /// 结束时间
public TimeHelper(int[] workingTime,int beginOfDay,int ennOfDay)
{
WorkingTime = workingTime;
BeginOfDay = beginOfDay;
EndOfDay = ennOfDay;
}
-
+ ///
+ /// 合约号前缀获取交易所时间
+ ///
+ /// 合约
+ /// 返回合约属性
public static EnumTradingTime GetTradingTime(string instrument)
{
- string prefix = instrument.Substring(0, 2);
+ string prefix = instrument.Substring(0, 2);//得到前缀2个字符
switch(prefix)
{
case "IF":
@@ -95,7 +120,11 @@ public static EnumTradingTime GetTradingTime(string instrument)
return EnumTradingTime.COMMODITY;
}
}
-
+ ///
+ /// 确定是否Trading时间
+ ///
+ ///
+ ///
public bool IsTradingTime(int time)
{
int index = -1;
@@ -113,24 +142,35 @@ public bool IsTradingTime(int time)
if (index % 2 == 0)
{
- // 交易时段
+ // Trading时段
return true;
}
- // 非交易时段
+ // 非Trading时段
return false;
}
-
+ ///
+ /// 把时间换成为数字表示。如915表示9:15分
+ ///
+ ///
+ ///
public int GetTime(DateTime dt)
{
return dt.Hour * 100 + dt.Minute;
}
-
+ ///
+ /// 确定是否Trading时间
+ ///
+ /// 时间参数
+ ///
public bool IsTradingTime(DateTime dt)
{
return IsTradingTime(GetTime(dt));
}
-
+ ///
+ /// 是否交易时间
+ ///
+ ///
public bool IsTradingTime()
{
return IsTradingTime(Clock.Now);
diff --git a/Demo/QuantBox.OQ.Demo/Helper/TimeHelper.cs.orig b/Demo/QuantBox.OQ.Demo/Helper/TimeHelper.cs.orig
new file mode 100644
index 0000000..adba25c
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo/Helper/TimeHelper.cs.orig
@@ -0,0 +1,219 @@
+using OpenQuant.API;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace QuantBox.OQ.Demo.Helper
+{
+ public enum EnumTradingTime
+ {
+ FINANCIAL, // 金融
+ COMMODITY, // 商品
+ COMMODITY_0230, // 黄金、白银
+ COMMODITY_0100,
+ }
+ ///
+ /// 时间助手
+ ///
+ public class TimeHelper
+ {
+ ///
+ /// 交易时间
+ ///
+ public int[] WorkingTime;
+ ///
+ /// 结束时间
+ ///
+ public int EndOfDay { get; private set; }
+ ///
+ /// 开始时间
+ ///
+ public int BeginOfDay { get; private set; }
+
+ public int[] WorkingTime_Financial = { 915, 1130, 1300, 1515 }; //IF,TF,IO
+ public int[] WorkingTime_Commodity = { 900, 1015, 1030, 1130, 1330, 1500 }; //商品
+ public int[] WorkingTime_Commodity_0230 = { 0, 230, 900, 1015, 1030, 1130, 1330, 1500, 2100, 2400 };//au,ag
+ public int[] WorkingTime_Commodity_0100 = { 0, 100, 900, 1015, 1030, 1130, 1330, 1500, 2100, 2400 };//铜、铝、铅、锌
+
+ private int EndOfDay_Financial = 1515; //IF 结束时间
+ private int EndOfDay_Commodity = 1500; //商品结束时间
+
+ private int BeginOfDay_Financial = 915;//上期所的开始时间
+ private int BeginOfDay_Commodity = 900;//商品的开始时间
+ private int BeginOfDay_Commodity_0230 = 2100;
+ private int BeginOfDay_Commodity_0100 = 2100;
+ ///
+<<<<<<< HEAD
+ /// 确定开收盘时间
+ /// 构造函数,根据合约属性确定开盘、收盘和交易时间
+ ///
+=======
+ /// 时间助手,根据所属交易所的类型确定交易时间
+ ///
+ ///
+>>>>>>> ea6f02b26addf16158c8567adeedbd21d778379a
+ public TimeHelper(EnumTradingTime tt)
+ {
+ switch(tt)
+ {
+ case EnumTradingTime.FINANCIAL:
+ WorkingTime = WorkingTime_Financial;
+ EndOfDay = EndOfDay_Financial;
+ BeginOfDay = BeginOfDay_Financial;
+ break;
+ case EnumTradingTime.COMMODITY:
+ WorkingTime = WorkingTime_Commodity;
+ EndOfDay = EndOfDay_Commodity;
+ BeginOfDay = BeginOfDay_Commodity;
+ break;
+ case EnumTradingTime.COMMODITY_0230:
+ WorkingTime = WorkingTime_Commodity_0230;
+ EndOfDay = EndOfDay_Commodity;
+ BeginOfDay = BeginOfDay_Commodity_0230;
+ break;
+ case EnumTradingTime.COMMODITY_0100:
+ WorkingTime = WorkingTime_Commodity_0100;
+ EndOfDay = EndOfDay_Commodity;
+ BeginOfDay = BeginOfDay_Commodity_0100;
+ break;
+ }
+ }
+ ///
+ /// 构造函数:根据合约ID确定开盘、收盘、交易时间
+ ///
+ ///
+ public TimeHelper(string instrument):this(GetTradingTime(instrument))
+ {
+ }
+ ///
+<<<<<<< HEAD
+ /// 构造函数:设置开盘、收盘、交易时间
+ ///
+ ///
+=======
+ /// 时间助手构造函数
+ ///
+ /// 交易时间
+ /// 开始时间
+ /// 结束时间
+>>>>>>> ea6f02b26addf16158c8567adeedbd21d778379a
+ public TimeHelper(int[] workingTime,int beginOfDay,int ennOfDay)
+ {
+ WorkingTime = workingTime;
+ BeginOfDay = beginOfDay;
+ EndOfDay = ennOfDay;
+ }
+ ///
+<<<<<<< HEAD
+ /// 获取指定合约的Trading时间
+ ///
+ /// 合约
+ /// 返回合约属性
+=======
+ /// 合约号前缀获取交易所时间
+ ///
+ ///
+ ///
+>>>>>>> ea6f02b26addf16158c8567adeedbd21d778379a
+ public static EnumTradingTime GetTradingTime(string instrument)
+ {
+ string prefix = instrument.Substring(0, 2);//得到前缀2个字符
+ switch(prefix)
+ {
+ case "IF":
+ case "TF":
+ case "IO":
+ case "IH":
+ case "IC":
+ case "HO":
+ return EnumTradingTime.FINANCIAL;
+ case "au":
+ case "ag":
+ return EnumTradingTime.COMMODITY_0230;
+ case "cu":
+ case "al":
+ case "pb":
+ case "zn":
+ return EnumTradingTime.COMMODITY_0100;
+ default:
+ return EnumTradingTime.COMMODITY;
+ }
+ }
+ ///
+<<<<<<< HEAD
+ /// 确定是否Trading时间
+ ///
+ ///
+=======
+ /// 时否交易时间
+ ///
+ /// 整型参数
+>>>>>>> ea6f02b26addf16158c8567adeedbd21d778379a
+ ///
+ public bool IsTradingTime(int time)
+ {
+ int index = -1;
+ for (int i = 0; i < WorkingTime.Length; ++i)
+ {
+ if (time < WorkingTime[i])
+ {
+ break;
+ }
+ else
+ {
+ index = i;
+ }
+ }
+
+ if (index % 2 == 0)
+ {
+ // Trading时段
+ return true;
+ }
+
+ // 非Trading时段
+ return false;
+ }
+ ///
+<<<<<<< HEAD
+ /// 把时间换成为数字表示。如915表示9:15分
+=======
+ /// 得到数字表示的时间,形如9:15表示为915
+>>>>>>> ea6f02b26addf16158c8567adeedbd21d778379a
+ ///
+ ///
+ ///
+ public int GetTime(DateTime dt)
+ {
+ return dt.Hour * 100 + dt.Minute;
+ }
+ ///
+<<<<<<< HEAD
+ /// 确定是否Trading时间
+ ///
+ ///
+=======
+ /// 时否交易时间
+ ///
+ /// 时间参数
+>>>>>>> ea6f02b26addf16158c8567adeedbd21d778379a
+ ///
+ public bool IsTradingTime(DateTime dt)
+ {
+ return IsTradingTime(GetTime(dt));
+ }
+ ///
+<<<<<<< HEAD
+ /// 确定是否Trading时间
+=======
+ /// 是否交易时间
+>>>>>>> ea6f02b26addf16158c8567adeedbd21d778379a
+ ///
+ ///
+ public bool IsTradingTime()
+ {
+ return IsTradingTime(Clock.Now);
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Indicator/DPO1.cs b/Demo/QuantBox.OQ.Demo/Indicator/DPO1.cs
index e697488..14f5f4d 100644
--- a/Demo/QuantBox.OQ.Demo/Indicator/DPO1.cs
+++ b/Demo/QuantBox.OQ.Demo/Indicator/DPO1.cs
@@ -20,9 +20,9 @@ public class DPO1 : UserIndicator
public DPO1(ISeries series, int length, BarData barData)
: base(series)
{
- this.length = length;
- this.option = barData;
- this.Name = "DPO";
+ this.length = length;//长度
+ this.option = barData;//bar类型
+ this.Name = "DPO";//名称
}
public override double Calculate(int index)
diff --git a/Demo/QuantBox.OQ.Demo/Indicator/KaufmanAMA.cs b/Demo/QuantBox.OQ.Demo/Indicator/KaufmanAMA.cs
index 684d869..65a02fd 100644
--- a/Demo/QuantBox.OQ.Demo/Indicator/KaufmanAMA.cs
+++ b/Demo/QuantBox.OQ.Demo/Indicator/KaufmanAMA.cs
@@ -1,73 +1,73 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-namespace QuantBox.OQ.Demo.Indicator
-{
- ///
- /// Kaufman自适应移动平均
- ///
- public class KaufmanAMA : UserIndicator
- {
- int n, p, q;
- // 效率系数
- public TimeSeries ER = new TimeSeries("ER");
-
- public KaufmanAMA(ISeries series, int n, int p, int q)
- : base(series)
- {
- this.n = n;
- this.p = p;
- this.q = q;
- this.Name = string.Format("KaufmanAMA({0},{1},{2})", n, p, q);
- }
-
- public override double Calculate(int index)
- {
- int j = index - n;
- if (j < 0)
- return double.NaN;
-
- DateTime dt = Input.GetDateTime(index);
-
- double DIRECTION = Math.Abs(Input[index, BarData.Close] - Input[j, BarData.Close]);
-
- double VOLATILITY = 0;
- for (int i = j; i < index; ++i)
- {
- VOLATILITY += Math.Abs(Input[i + 1, BarData.Close] - Input[i, BarData.Close]);
- }
- //return VOLATILITY;
-
- double _ER = DIRECTION / VOLATILITY; //{EFFICIENCY RATIO是AMA系统中最重要的指标,比值越大,趋势越明显}
- if (VOLATILITY == 0)
- {
- _ER = 1;
- }
- ER.Add(dt, _ER);
- //return ER;
-
- double FSC = 2.0 / (1.0 + p); // {快速平滑常数}
- double SSC = 2.0 / (1.0 + q); // {慢速平滑常数}
- double SC = _ER * (FSC - SSC) + SSC; //{等价于SC=ER*FSC+(1-ER)*SSC,指数平滑序列}
- double SCSQ = SC * SC;
-
- double db = Input[index, BarData.Close];
-
- if (j == 0)
- {
- }
- else
- {
- db = SCSQ * db + (1 - SCSQ) * this[j - 1];
- }
-
- return db;
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+namespace QuantBox.OQ.Demo.Indicator
+{
+ ///
+ /// Kaufman自适应移动平均
+ ///
+ public class KaufmanAMA : UserIndicator
+ {
+ int n, p, q;
+ // 效率系数
+ public TimeSeries ER = new TimeSeries("ER");
+
+ public KaufmanAMA(ISeries series, int n, int p, int q)
+ : base(series)
+ {
+ this.n = n;
+ this.p = p;
+ this.q = q;
+ this.Name = string.Format("KaufmanAMA({0},{1},{2})", n, p, q);
+ }
+
+ public override double Calculate(int index)
+ {
+ int j = index - n;
+ if (j < 0)
+ return double.NaN;
+
+ DateTime dt = Input.GetDateTime(index);
+
+ double DIRECTION = Math.Abs(Input[index, BarData.Close] - Input[j, BarData.Close]);
+
+ double VOLATILITY = 0;
+ for (int i = j; i < index; ++i)
+ {
+ VOLATILITY += Math.Abs(Input[i + 1, BarData.Close] - Input[i, BarData.Close]);
+ }
+ //return VOLATILITY;
+
+ double _ER = DIRECTION / VOLATILITY; //{EFFICIENCY RATIO是AMA系统中最重要的指标,比值越大,趋势越明显}
+ if (VOLATILITY == 0)
+ {
+ _ER = 1;
+ }
+ ER.Add(dt, _ER);
+ //return ER;
+
+ double FSC = 2.0 / (1.0 + p); // {快速平滑常数}
+ double SSC = 2.0 / (1.0 + q); // {慢速平滑常数}
+ double SC = _ER * (FSC - SSC) + SSC; //{等价于SC=ER*FSC+(1-ER)*SSC,指数平滑序列}
+ double SCSQ = SC * SC;
+
+ double db = Input[index, BarData.Close];
+
+ if (j == 0)
+ {
+ }
+ else
+ {
+ db = SCSQ * db + (1 - SCSQ) * this[j - 1];
+ }
+
+ return db;
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Indicator/Test/DynamicBBU_code.cs b/Demo/QuantBox.OQ.Demo/Indicator/Test/DynamicBBU_code.cs
index 81a3176..5d2e531 100644
--- a/Demo/QuantBox.OQ.Demo/Indicator/Test/DynamicBBU_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Indicator/Test/DynamicBBU_code.cs
@@ -1,41 +1,41 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-namespace QuantBox.OQ.Demo.Indicator.Test
-{
- public class DynamicBBU_code : Strategy
- {
- DynamicBBU dbbu;
- TimeSeries lengths = new TimeSeries("Lengths");
-
- public override void OnStrategyStart()
- {
- dbbu = new DynamicBBU(lengths, Bars, 2, BarData.Close);
-
- Draw(dbbu, 0);
- Draw(dbbu.BBL, 0);
- Draw(dbbu.SMA, 0);
- Draw(dbbu.VAR, 2);
-
- Draw(lengths, 3);
- }
-
-
-
- public override void OnBar(Bar bar)
- {
-
- // 这个地方是关键
- lengths.Add(bar.DateTime, 5);
-
- // 别的就自己写吧
-
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+namespace QuantBox.OQ.Demo.Indicator.Test
+{
+ public class DynamicBBU_code : Strategy
+ {
+ DynamicBBU dbbu;
+ TimeSeries lengths = new TimeSeries("Lengths");
+
+ public override void OnStrategyStart()
+ {
+ dbbu = new DynamicBBU(lengths, Bars, 2, BarData.Close);
+
+ Draw(dbbu, 0);
+ Draw(dbbu.BBL, 0);
+ Draw(dbbu.SMA, 0);
+ Draw(dbbu.VAR, 2);
+
+ Draw(lengths, 3);
+ }
+
+
+
+ public override void OnBar(Bar bar)
+ {
+
+ // 这个地方是关键
+ lengths.Add(bar.DateTime, 5);
+
+ // 别的就自己写吧
+
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Module/TargetOrderBookModule.cs b/Demo/QuantBox.OQ.Demo/Module/TargetOrderBookModule.cs
index 3f68ecd..797d7ef 100644
--- a/Demo/QuantBox.OQ.Demo/Module/TargetOrderBookModule.cs
+++ b/Demo/QuantBox.OQ.Demo/Module/TargetOrderBookModule.cs
@@ -8,6 +8,9 @@
namespace QuantBox.OQ.Demo.Module
{
+ ///
+ /// 目标挂单助手
+ ///
public class TargetOrderBookModule : TargetPositionModule
{
class CopyOrder
diff --git a/Demo/QuantBox.OQ.Demo/Module/TargetPositionModule.cs b/Demo/QuantBox.OQ.Demo/Module/TargetPositionModule.cs
index 6b0d2e1..ce09f67 100644
--- a/Demo/QuantBox.OQ.Demo/Module/TargetPositionModule.cs
+++ b/Demo/QuantBox.OQ.Demo/Module/TargetPositionModule.cs
@@ -1,562 +1,606 @@
-using OpenQuant.API;
-using QuantBox.OQ.Demo.Helper;
-using QuantBox.OQ.Extensions;
-using QuantBox.OQ.Extensions.OrderText;
-using System;
-
-namespace QuantBox.OQ.Demo.Module
-{
- public class TargetPositionModule : Strategy
- {
- public DualPosition DualPosition;
- ///
- /// 目标仓位
- ///
- public double TargetPosition = 0;
- ///
- /// 每笔最大手数
- ///
- [Parameter("每笔最大手数", "TargetPositionModule")]
- public double MaxQtyPerLot = 5;
- ///
- /// 小于等于此数量的开仓单自动以市价发送
- ///
- [Parameter("小于等于此数量的开仓单自动以市价发送", "TargetPositionModule")]
- public double MarketOpenQtyThreshold = 5;
- ///
- /// 小于等于此数量的平仓单自动以市价发送
- ///
- [Parameter("小于等于此数量的平仓单自动以市价发送", "TargetPositionModule")]
- public double MarketCloseQtyThreshold = 20;
- ///
- /// 对手价上加N跳下单
- ///
- [Parameter("对手价上加N跳下单", "TargetPositionModule")]
- public int Jump = 2;
-
- protected TimeHelper TimeHelper;
- protected PriceHelper PriceHelper;
- protected CloseTodayHelper CloseTodayHelper;
-
- protected TextCommon TextParameter;
-
- ///
- /// 入场后的最高价,用于跟踪止损
- ///
- public double HighestAfterEntry = double.MinValue;
- ///
- /// 入场后的最低价,用于跟踪止损
- ///
- public double LowestAfterEntry = double.MaxValue;
-
- ///
- /// 在进行各项计算时到底是使用信号持仓还是实盘持仓呢?
- ///
- ///
- public virtual double GetCurrentQty()
- {
- // 各项处理时使用实盘持仓
- return DualPosition.NetQty;
- // 各项处理时使用信号持仓
- //return TargetPosition;
- }
-
- public virtual double GetLongAvgPrice()
- {
- return DualPosition.Long.AvgPrice;
- }
-
- public virtual double GetShortAvgPrice()
- {
- return DualPosition.Short.AvgPrice;
- }
-
- ///
- /// 计算入场后的最高价与最低价
- ///
- ///
- public void HiLoAfterEntry(double price)
- {
- double qty = GetCurrentQty();
- if (qty == 0)
- {
- HighestAfterEntry = double.MinValue;
- LowestAfterEntry = double.MaxValue;
- }
- else
- {
- HighestAfterEntry = Math.Max(HighestAfterEntry, price);
- LowestAfterEntry = Math.Min(LowestAfterEntry, price);
- }
- }
-
- public override void OnStrategyStart()
- {
- TimeHelper = new TimeHelper(Instrument.Symbol);
- PriceHelper = new PriceHelper(Instrument.TickSize);
- TextParameter = new TextCommon() { OpenClose = EnumOpenClose.OPEN };
- CloseTodayHelper = new CloseTodayHelper(EnumExchangeID.SHFE);
-
- DualPosition = new DualPosition(Instrument.Symbol);
- DualPosition.Sell.PriceHelper = PriceHelper;
- DualPosition.Buy.PriceHelper = PriceHelper;
- DualPosition.CloseTodayHelper = CloseTodayHelper;
-
- TargetPosition = 0;
- DualPosition.Long.Qty = 0;
- DualPosition.Long.QtyToday = 0;
- DualPosition.Short.Qty = 0;
- DualPosition.Short.QtyToday = 0;
- }
-
- public override void OnTrade(Trade trade)
- {
- //lock(this)
- {
- Process();
- }
- HiLoAfterEntry(trade.Price);
- }
-
- public override void OnQuote(Quote quote)
- {
- //lock(this)
- {
- Process();
- }
-
- // 如果只有Quote数据,如何更新?
- // 那就会不用这个目标仓位助手了
- //if(!DataRequests.HasTradeRequest)
- //{
- //}
- }
-
- public override void OnBarOpen(Bar bar)
- {
- //lock(this)
- {
- Process();
- }
- HiLoAfterEntry(bar.Open);
- }
-
- public override void OnBar(Bar bar)
- {
- //lock(this)
- {
- Process();
- }
- HiLoAfterEntry(bar.Close);
- }
-
- ///
- /// 进行下单,最小手续费处理原则
- ///
- public virtual void Process()
- {
- // 非交易时段,不处理
- if (!TimeHelper.IsTradingTime())
- {
- return;
- }
-
- double qty = 0;
- OrderSide Side = OrderSide.Buy;
- TextParameter.OpenClose = EnumOpenClose.OPEN;
-
- lock(this)
- {
- // 计算仓差
- double dif = TargetPosition - DualPosition.NetQty;
-
- if (dif == 0)// 持仓量相等
- {
- // 把所有的挂单全撤了
- DualPosition.Cancel();
- return;
- }
- else if (dif > 0 && !DualPosition.IsPending)// 表示要增加净持仓
- {
- // 是否有在途增仓订单,超数了
- // 是否有在途减仓订单,全取消息
- qty = dif;
- Side = OrderSide.Buy;
-
- EnumOpenClose oc = EnumOpenClose.CLOSE;
- double q = CloseTodayHelper.GetCloseAndQty(DualPosition.Short, out oc);
- if (q > 0)
- {
- // 按最小数量进行平仓
- qty = Math.Min(qty, q);
- TextParameter.OpenClose = oc;
- }
- }
- else if (!DualPosition.IsPending) // 减少净持仓
- {
- qty = -dif;
- Side = OrderSide.Sell;
-
- EnumOpenClose oc = EnumOpenClose.CLOSE;
- double q = CloseTodayHelper.GetCloseAndQty(DualPosition.Long, out oc);
- if (q > 0)
- {
- // 按最小数量进行平仓
- qty = Math.Min(qty, q);
- TextParameter.OpenClose = oc;
- }
- }
-
- if (qty > 0)
- {
- qty = Math.Min(qty, MaxQtyPerLot);
-
- // 下单
- SendOrder(Side, qty);
- }
- }
- }
-
- ///
- /// 下单
- ///
- ///
- ///
- public void SendOrder(OrderSide side, double qty)
- {
- if (!TimeHelper.IsTradingTime())
- {
- return;
- }
-
- if (qty <= 0)
- {
- return;
- }
-
- // 为减少滑点,对数量少的单子直接市价单
- bool bMarketOrder = false;
- if (EnumOpenClose.OPEN == TextParameter.OpenClose)
- {
- if (qty <= MarketOpenQtyThreshold)
- bMarketOrder = true;
- }
- else
- {
- if (qty <= MarketCloseQtyThreshold)
- bMarketOrder = true;
- }
-
- //lock(this)
- {
- if (bMarketOrder)
- {
- SendMarketOrder(side, qty, TextParameter.ToString());
- }
- else
- {
- SendLimitOrder(side, qty, PriceHelper.GetMatchPrice(this, side, Jump), TextParameter.ToString());
- }
- }
- }
-
- ///
- /// 重新发单
- ///
- ///
- public void ResendOrder(Order order)
- {
- SendOrder(order.Side, order.LeavesQty);
- }
-
- public override void OnOrderPartiallyFilled(Order order)
- {
- double LastPrice = order.LastPrice;
- //lock(this)
- {
- DualPosition.Filled(order);
-
- // 单子部分成交,不做操作,等单子完全执行完
- // 等交易完,会有问题,一直挂在上面不操作,新单子也过不来
- //Process();
- }
- HiLoAfterEntry(LastPrice);
- }
-
- public override void OnOrderFilled(Order order)
- {
- double LastPrice = order.LastPrice;
- //lock(this)
- {
- DualPosition.Filled(order);
-
- // 检查仓位是否正确,是否要发新单
- //Process();
- }
- HiLoAfterEntry(LastPrice);
- }
-
- public override void OnNewOrder(Order order)
- {
- //lock(this)
- {
- DualPosition.NewOrder(order);
-
- // 得加定时器,一定的时间内没有成交完全应当撤单重发,目前没有加这一功能
- }
- }
-
- public override void OnOrderRejected(Order order)
- {
- double LeavesQty = order.LeavesQty;
- double flag = order.Side == OrderSide.Buy ? 1 : -1;
- EnumOpenClose OpenClose = DualPosition.OrderRejected(order);
-
- lock(this)
- {
- if (EnumOpenClose.OPEN == OpenClose)
- {
- // 开仓被拒绝,不再新开仓
- // 有可能是钱不够
- // 有可能是超出持仓限制
- // 有可能是非交易时间
- TargetPosition -= flag * LeavesQty;
- return;
- }
-
- EnumError error = TextResponse.FromText(order.Text);
-
- // 无法平仓,不重发单
- // 能出现这个问题是持仓计算错误,这已经是策略持仓计算错误了
- if (error == EnumError.OVER_CLOSETODAY_POSITION
- || error == EnumError.OVER_CLOSEYESTERDAY_POSITION
- || error == EnumError.OVER_CLOSE_POSITION)
- {
- TargetPosition -= flag * LeavesQty;
- return;
- }
-
- // 当前状态禁止此项操作,时间不对,应当等下次操作
- }
- }
-
- public override void OnOrderCancelled(Order order)
- {
- //lock(this)
- {
- DualPosition.OrderCancelled(order);
-
- // 这个地方会影响做市商的挂单功能
- //ResendOrder(order);
- }
- }
-
- public override void OnOrderCancelReject(Order order)
- {
- // 撤单被拒绝,暂不操作
- }
-
- ///
- /// 根据入场后的最高与最低价,跟踪止损
- ///
- ///
- ///
- ///
- /// 止损了返止损前持仓,可用于后面的反手
- public virtual double TrailingStop(double currentPrice, double level, StopMode mode,string text)
- {
- //lock(this)
- {
- double qty = GetCurrentQty();
- double stop;
- if (qty > double.Epsilon)
- {
- if (StopMode.Percent == mode)
- {
- stop = HighestAfterEntry * (1.0 - level);
- }
- else
- {
- stop = HighestAfterEntry - level;
- }
- if (currentPrice < stop)
- {
- TargetPosition = 0;
- TextParameter.Text = string.Format("跟踪止损 - 最高{0},止损{1}>当前{2}|{3}",
- HighestAfterEntry, stop, currentPrice,
- text);
- return qty;
- }
- }
- else if (qty < -double.Epsilon)
- {
- if (StopMode.Percent == mode)
- {
- stop = LowestAfterEntry * (1.0 + level);
- }
- else
- {
- stop = LowestAfterEntry + level;
- }
-
- if (currentPrice > stop)
- {
- TargetPosition = 0;
- TextParameter.Text = string.Format("跟踪止损 - 最低{0},止损{1}<当前{2}|{3}",
- HighestAfterEntry, stop, currentPrice,
- text);
- return qty;
- }
- }
-
- return 0;
- }
- }
-
- ///
- /// 从入场均价开始算起,固定点位止损
- ///
- ///
- ///
- ///
- /// 止损了返止损前持仓,可用于后面的反手
- public virtual double FixedStop(double currentPrice, double level, StopMode mode, string text)
- {
- //lock(this)
- {
- double qty = GetCurrentQty();
- double stop;
- if (qty > double.Epsilon)
- {
- if (StopMode.Percent == mode)
- {
- stop = GetLongAvgPrice() * (1.0 - level);
- }
- else
- {
- stop = GetLongAvgPrice() - level;
- }
- if (currentPrice < stop)
- {
- TargetPosition = 0;
- TextParameter.Text = string.Format("固定止损 - 多头均价{0},止损{1}>当前{2}|{3}",
- GetLongAvgPrice(), stop, currentPrice,
- text);
- return qty;
- }
- }
- else if (qty < -double.Epsilon)
- {
- if (StopMode.Percent == mode)
- {
- stop = GetShortAvgPrice() * (1.0 + level);
- }
- else
- {
- stop = GetShortAvgPrice() + level;
- }
-
- if (currentPrice > stop)
- {
- TargetPosition = 0;
- TextParameter.Text = string.Format("固定止损 - 空头均价{0},止损{1}<当前{2}|{3}",
- GetShortAvgPrice(), stop, currentPrice,
- text);
- return qty;
- }
- }
- return 0;
- }
- }
-
- public virtual double TakeProfit(double currentPrice, double level, StopMode mode, string text)
- {
- //lock(this)
- {
- double qty = GetCurrentQty();
- double stop;
- if (qty > double.Epsilon)
- {
- if (StopMode.Percent == mode)
- {
- stop = GetLongAvgPrice() * (1.0 + level);
- }
- else
- {
- stop = GetLongAvgPrice() + level;
- }
- if (currentPrice > stop)
- {
- TargetPosition = 0;
- TextParameter.Text = string.Format("固定止赢 - 多头均价{0},止赢{1}<当前{2}|{3}",
- GetLongAvgPrice(), stop, currentPrice,
- text);
- return qty;
- }
- }
- else if (qty < -double.Epsilon)
- {
- if (StopMode.Percent == mode)
- {
- stop = GetShortAvgPrice() * (1.0 - level);
- }
- else
- {
- stop = GetShortAvgPrice() - level;
- }
-
- if (currentPrice < stop)
- {
- TargetPosition = 0;
- TextParameter.Text = string.Format("固定止赢 - 空头均价{0},止赢{1}>当前{2}|{3}",
- GetShortAvgPrice(), stop, currentPrice,
- text);
- return qty;
- }
- }
- return 0;
- }
- }
-
- ///
- /// 尾盘清仓
- ///
- /// 返回上次持仓量
- public virtual double ExitOnClose(double seconds,string text)
- {
- //lock(this)
- {
- double qty = GetCurrentQty();
- if (TimeHelper.GetTime(Clock.Now.AddSeconds(seconds)) >= TimeHelper.EndOfDay)
- {
- TargetPosition = 0;
- TextParameter.Text = string.Format("尾盘,清仓|{0}", text);
- return qty;
- }
- return 0;
- }
- }
-
- public virtual void ChangeTradingDay()
- {
- if (TimeHelper.BeginOfDay > TimeHelper.EndOfDay)
- {
- // 夜盘
- if (TimeHelper.GetTime(Clock.Now) > TimeHelper.EndOfDay
- && TimeHelper.GetTime(Clock.Now) < TimeHelper.BeginOfDay)
- {
- DualPosition.ChangeTradingDay();
- }
- }
- else
- {
- if (TimeHelper.GetTime(Clock.Now) > TimeHelper.EndOfDay
- || TimeHelper.GetTime(Clock.Now) < TimeHelper.BeginOfDay)
- {
- DualPosition.ChangeTradingDay();
- }
- }
- }
- }
-
-}
+using OpenQuant.API;
+using QuantBox.OQ.Demo.Helper;
+using QuantBox.OQ.Extensions;
+using QuantBox.OQ.Extensions.OrderText;
+using System;
+
+namespace QuantBox.OQ.Demo.Module
+{
+ ///
+ /// 目标仓位助手
+ ///
+ public class TargetPositionModule : Strategy
+ {
+ public DualPosition DualPosition;
+ ///
+ /// 目标仓位
+ ///
+ public double TargetPosition = 0;
+ ///
+ /// 每笔最大手数
+ ///
+ [Parameter("每笔最大手数", "TargetPositionModule")]
+ public double MaxQtyPerLot = 5;
+ ///
+ /// 小于等于此数量的开仓单自动以市价发送
+ ///
+ [Parameter("小于等于此数量的开仓单自动以市价发送", "TargetPositionModule")]
+ public double MarketOpenQtyThreshold = 5;
+ ///
+ /// 小于等于此数量的平仓单自动以市价发送
+ ///
+ [Parameter("小于等于此数量的平仓单自动以市价发送", "TargetPositionModule")]
+ public double MarketCloseQtyThreshold = 20;
+ ///
+ /// 对手价上加N跳下单
+ ///
+ [Parameter("对手价上加N跳下单", "TargetPositionModule")]
+ public int Jump = 2;
+
+ protected TimeHelper TimeHelper;//时间助手
+ protected PriceHelper PriceHelper;//价格助手
+ protected CloseTodayHelper CloseTodayHelper;//平今仓助手
+
+ protected TextCommon TextParameter;//文本参数,显示交易命令参数
+
+ ///
+ /// 入场后的最高价,用于跟踪止损
+ ///
+ public double HighestAfterEntry = double.MinValue;
+ ///
+ /// 入场后的最低价,用于跟踪止损
+ ///
+ public double LowestAfterEntry = double.MaxValue;
+
+ ///
+ /// 获取当前持仓
+ /// 在进行各项计算时到底是使用信号持仓还是实盘持仓呢?
+ ///
+ ///
+ public virtual double GetCurrentQty()
+ {
+ // 各项处理时使用实盘持仓
+ return DualPosition.NetQty;
+ // 各项处理时使用信号持仓
+ //return TargetPosition;
+ }
+ ///
+ /// 取得多头持仓平均成本
+ ///
+ ///
+ public virtual double GetLongAvgPrice()
+ {
+ return DualPosition.Long.AvgPrice;
+ }
+ ///
+ /// 取得空头持仓平均成本
+ ///
+ ///
+ public virtual double GetShortAvgPrice()
+ {
+ return DualPosition.Short.AvgPrice;
+ }
+
+ ///
+ /// 计算入场后的最高价与最低价
+ ///
+ ///
+ public void HiLoAfterEntry(double price)
+ {
+ double qty = GetCurrentQty();
+ if (qty == 0)
+ {
+ HighestAfterEntry = double.MinValue;
+ LowestAfterEntry = double.MaxValue;
+ }
+ else
+ {
+ HighestAfterEntry = Math.Max(HighestAfterEntry, price);
+ LowestAfterEntry = Math.Min(LowestAfterEntry, price);
+ }
+ }
+
+ public override void OnStrategyStart()
+ {
+ TimeHelper = new TimeHelper(Instrument.Symbol);
+ PriceHelper = new PriceHelper(Instrument.TickSize);
+ TextParameter = new TextCommon() { OpenClose = EnumOpenClose.OPEN };
+ CloseTodayHelper = new CloseTodayHelper(EnumExchangeID.SHFE);
+
+ DualPosition = new DualPosition(Instrument.Symbol);
+ DualPosition.Sell.PriceHelper = PriceHelper;
+ DualPosition.Buy.PriceHelper = PriceHelper;
+ DualPosition.CloseTodayHelper = CloseTodayHelper;
+
+ TargetPosition = 0;//仓位初始化
+ DualPosition.Long.Qty = 0;
+ DualPosition.Long.QtyToday = 0;
+ DualPosition.Short.Qty = 0;
+ DualPosition.Short.QtyToday = 0;
+ }
+
+ public override void OnTrade(Trade trade)
+ {
+ //lock(this)
+ {
+ Process();
+ }
+ HiLoAfterEntry(trade.Price);
+ }
+
+ public override void OnQuote(Quote quote)
+ {
+ //lock(this)
+ {
+ Process();
+ }
+
+ // 如果只有Quote数据,如何更新?
+ // 那就会不用这个目标仓位助手了
+ //if(!DataRequests.HasTradeRequest)
+ //{
+ //}
+ }
+ ///
+ /// OpenBar事件
+ ///
+ ///
+ public override void OnBarOpen(Bar bar)
+ {
+ //lock(this)
+ {
+ Process();
+ }
+ HiLoAfterEntry(bar.Open);
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ //lock(this)
+ {
+ Process();
+ }
+ HiLoAfterEntry(bar.Close);
+ }
+
+ ///
+ /// 进行下单,最小手续费处理原则
+ ///
+ public virtual void Process()
+ {
+ // 非交易时段,不处理
+ if (!TimeHelper.IsTradingTime())
+ {
+ return;
+ }
+
+ double qty = 0;
+ OrderSide Side = OrderSide.Buy;
+ TextParameter.OpenClose = EnumOpenClose.OPEN;
+
+ lock(this)
+ {
+ // 计算仓差 = 目标持仓 - 实际持仓(多头挂仓量-空头持仓量)
+ double dif = TargetPosition - DualPosition.NetQty;
+
+ if (dif == 0)// 多仓=空仓,持仓量相等
+ {
+ // 把所有的挂单全撤了
+ DualPosition.Cancel();
+ return;
+ }
+ else if (dif > 0 && !DualPosition.IsPending)// 表示要增加净持仓
+ {
+ // 是否有在途增仓订单,超数了
+ // 是否有在途减仓订单,全取消息
+ qty = dif;
+ Side = OrderSide.Buy;
+
+ EnumOpenClose oc = EnumOpenClose.CLOSE;
+ double q = CloseTodayHelper.GetCloseAndQty(DualPosition.Short, out oc);
+ if (q > 0)
+ {
+ // 按最小数量进行平仓
+ qty = Math.Min(qty, q);
+ TextParameter.OpenClose = oc;
+ }
+ }
+ else if (!DualPosition.IsPending) // 减少净持仓
+ {
+ qty = -dif;
+ Side = OrderSide.Sell;
+
+ EnumOpenClose oc = EnumOpenClose.CLOSE;
+ double q = CloseTodayHelper.GetCloseAndQty(DualPosition.Long, out oc);
+ if (q > 0)
+ {
+ // 按最小数量进行平仓
+ qty = Math.Min(qty, q);
+ TextParameter.OpenClose = oc;
+ }
+ }
+
+ if (qty > 0)
+ {
+ qty = Math.Min(qty, MaxQtyPerLot);
+
+ // 下单
+ SendOrder(Side, qty);
+ }
+ }
+ }
+
+ ///
+ /// 下单
+ ///
+ ///
+ ///
+ public void SendOrder(OrderSide side, double qty)
+ {
+ if (!TimeHelper.IsTradingTime())
+ {
+ return;
+ }
+
+ if (qty <= 0)
+ {
+ return;
+ }
+
+ // 为减少滑点,对数量少的单子直接市价单
+ bool bMarketOrder = false;
+ if (EnumOpenClose.OPEN == TextParameter.OpenClose)
+ {
+ if (qty <= MarketOpenQtyThreshold)
+ bMarketOrder = true;
+ }
+ else
+ {
+ if (qty <= MarketCloseQtyThreshold)
+ bMarketOrder = true;
+ }
+
+ //lock(this)
+ {
+ if (bMarketOrder)
+ {
+ SendMarketOrder(side, qty, TextParameter.ToString());
+ }
+ else
+ {
+ SendLimitOrder(side, qty, PriceHelper.GetMatchPrice(this, side, Jump), TextParameter.ToString());
+ }
+ }
+ }
+
+ ///
+ /// 重新发单
+ ///
+ ///
+ public void ResendOrder(Order order)
+ {
+ SendOrder(order.Side, order.LeavesQty);
+ }
+
+ public override void OnOrderPartiallyFilled(Order order)
+ {
+ double LastPrice = order.LastPrice;
+ //lock(this)
+ {
+ DualPosition.Filled(order);
+
+ // 单子部分成交,不做操作,等单子完全执行完
+ // 等交易完,会有问题,一直挂在上面不操作,新单子也过不来
+ //Process();
+ }
+ HiLoAfterEntry(LastPrice);
+ }
+
+ public override void OnOrderFilled(Order order)
+ {
+ double LastPrice = order.LastPrice;
+ //lock(this)
+ {
+ DualPosition.Filled(order);
+
+ // 检查仓位是否正确,是否要发新单
+ //Process();
+ }
+ HiLoAfterEntry(LastPrice);
+ }
+ ///
+ /// 新增订单事件
+ ///
+ ///
+ public override void OnNewOrder(Order order)
+ {
+ //lock(this)
+ {
+ DualPosition.NewOrder(order);
+
+ // 得加定时器,一定的时间内没有成交完全应当撤单重发,目前没有加这一功能
+ }
+ }
+ ///
+ /// 订单被拒绝事件
+ ///
+ ///
+ public override void OnOrderRejected(Order order)
+ {
+ double LeavesQty = order.LeavesQty;
+ double flag = order.Side == OrderSide.Buy ? 1 : -1;
+ EnumOpenClose OpenClose = DualPosition.OrderRejected(order);
+
+ lock(this)
+ {
+ if (EnumOpenClose.OPEN == OpenClose)
+ {
+ // 开仓被拒绝,不再新开仓
+ // 有可能是钱不够
+ // 有可能是超出持仓限制
+ // 有可能是非交易时间
+ TargetPosition -= flag * LeavesQty;
+ return;
+ }
+
+ EnumError error = TextResponse.FromText(order.Text);
+
+ // 无法平仓,不重发单
+ // 能出现这个问题是持仓计算错误,这已经是策略持仓计算错误了
+ if (error == EnumError.OVER_CLOSETODAY_POSITION
+ || error == EnumError.OVER_CLOSEYESTERDAY_POSITION
+ || error == EnumError.OVER_CLOSE_POSITION)
+ {
+ TargetPosition -= flag * LeavesQty;
+ return;
+ }
+
+ // 当前状态禁止此项操作,时间不对,应当等下次操作
+ }
+ }
+ ///
+ /// 订单被取消事件
+ ///
+ ///
+ public override void OnOrderCancelled(Order order)
+ {
+ //lock(this)
+ {
+ DualPosition.OrderCancelled(order);
+
+ // 这个地方会影响做市商的挂单功能
+ //ResendOrder(order);
+ }
+ }
+ ///
+ /// 撤单被拒绝事件
+ ///
+ ///
+ public override void OnOrderCancelReject(Order order)
+ {
+ // 撤单被拒绝,暂不操作
+ }
+
+ ///
+ /// 根据入场后的最高与最低价,跟踪止损
+ ///
+ /// 当前价格
+ /// 止损水平:为绝对值或百分比
+ /// 止损类型:绝对值,Percent百分比
+ /// 止损了返回止损前持仓,可用于后面的反手
+ public virtual double TrailingStop(double currentPrice, double level, StopMode mode,string text)
+ {
+ //lock(this)
+ {
+ double qty = GetCurrentQty();//获取当前持仓
+ double stop;//止损价
+ //当前持仓 > 0 时
+ if (qty > double.Epsilon)
+ {
+ //止损类型为百分比时
+ if (StopMode.Percent == mode)
+ {
+ //止损价=入场后最高价*(1.0-止损百分比)
+ stop = HighestAfterEntry * (1.0 - level);
+ }
+ else//止损类型为绝对值
+ {
+ //止损价=入场后最高价 - 止损绝对值
+ stop = HighestAfterEntry - level;
+ }
+ //当前价格 < 止损价 时清仓
+ if (currentPrice < stop)
+ {
+ TargetPosition = 0;//目标仓位=0,表示清仓
+ TextParameter.Text = string.Format("跟踪止损 - 最高{0},止损{1}>当前{2}|{3}",
+ HighestAfterEntry, stop, currentPrice,
+ text);
+ return qty;//返回止损仓位,可用于后面的反手
+ }
+ }
+ //当前持仓 < 0 时
+ else if (qty < -double.Epsilon)
+ {
+ //止损类型为百分比时
+ if (StopMode.Percent == mode)
+ {
+ stop = LowestAfterEntry * (1.0 + level);
+ }
+ else//止损类型为绝对值
+ {
+ stop = LowestAfterEntry + level;
+ }
+
+ if (currentPrice > stop)
+ {
+ TargetPosition = 0;
+ TextParameter.Text = string.Format("跟踪止损 - 最低{0},止损{1}<当前{2}|{3}",
+ HighestAfterEntry, stop, currentPrice,
+ text);
+ return qty;
+ }
+ }
+
+ return 0;
+ }
+ }
+
+ ///
+ /// 从入场均价开始算起,固定点位止损
+ ///
+ /// 当前价
+ /// 止损水平
+ /// 止损类型
+ /// 止损了返止损前持仓,可用于后面的反手
+ public virtual double FixedStop(double currentPrice, double level, StopMode mode, string text)
+ {
+ //lock(this)
+ {
+ double qty = GetCurrentQty();//获取当前仓位
+ double stop;//止损价
+ //仓位>0时
+ if (qty > double.Epsilon)
+ {
+ //止损类型为百分比时
+ if (StopMode.Percent == mode)
+ {
+ stop = GetLongAvgPrice() * (1.0 - level);
+ }
+ else//止损类型为绝对值时
+ {
+ stop = GetLongAvgPrice() - level;
+ }
+ if (currentPrice < stop)
+ {
+ TargetPosition = 0;//清仓
+ TextParameter.Text = string.Format("固定止损 - 多头均价{0},止损{1}>当前{2}|{3}",
+ GetLongAvgPrice(), stop, currentPrice,
+ text);
+ return qty;
+ }
+ }
+ //仓位<0时
+ else if (qty < -double.Epsilon)
+ {
+ if (StopMode.Percent == mode)
+ {
+ stop = GetShortAvgPrice() * (1.0 + level);
+ }
+ else
+ {
+ stop = GetShortAvgPrice() + level;
+ }
+
+ if (currentPrice > stop)
+ {
+ TargetPosition = 0;
+ TextParameter.Text = string.Format("固定止损 - 空头均价{0},止损{1}<当前{2}|{3}",
+ GetShortAvgPrice(), stop, currentPrice,
+ text);
+ return qty;
+ }
+ }
+ return 0;
+ }
+ }
+ ///
+ /// 固定止赢
+ ///
+ /// 当前价格
+ ///
+ /// 获利停止类型:Absolute绝对,Percent百分比
+ ///
+ ///
+ public virtual double TakeProfit(double currentPrice, double level, StopMode mode, string text)
+ {
+ //lock(this)
+ {
+ double qty = GetCurrentQty();
+ double stop;
+ if (qty > double.Epsilon)
+ {
+ if (StopMode.Percent == mode)
+ {
+ stop = GetLongAvgPrice() * (1.0 + level);
+ }
+ else
+ {
+ stop = GetLongAvgPrice() + level;
+ }
+ if (currentPrice > stop)
+ {
+ TargetPosition = 0;
+ TextParameter.Text = string.Format("固定止赢 - 多头均价{0},止赢{1}<当前{2}|{3}",
+ GetLongAvgPrice(), stop, currentPrice,
+ text);
+ return qty;
+ }
+ }
+ else if (qty < -double.Epsilon)
+ {
+ if (StopMode.Percent == mode)
+ {
+ stop = GetShortAvgPrice() * (1.0 - level);
+ }
+ else
+ {
+ stop = GetShortAvgPrice() - level;
+ }
+
+ if (currentPrice < stop)
+ {
+ TargetPosition = 0;
+ TextParameter.Text = string.Format("固定止赢 - 空头均价{0},止赢{1}>当前{2}|{3}",
+ GetShortAvgPrice(), stop, currentPrice,
+ text);
+ return qty;
+ }
+ }
+ return 0;
+ }
+ }
+
+ ///
+ /// 尾盘清仓
+ ///
+ /// 返回上次持仓量
+ public virtual double ExitOnClose(double seconds,string text)
+ {
+ //lock(this)
+ {
+ double qty = GetCurrentQty();
+ if (TimeHelper.GetTime(Clock.Now.AddSeconds(seconds)) >= TimeHelper.EndOfDay)
+ {
+ TargetPosition = 0;
+ TextParameter.Text = string.Format("尾盘,清仓|{0}", text);
+ return qty;
+ }
+ return 0;
+ }
+ }
+ ///
+ /// 换日,用户自己要记得挂单要撤
+ ///
+ public virtual void ChangeTradingDay()
+ {
+ if (TimeHelper.BeginOfDay > TimeHelper.EndOfDay)
+ {
+ // 夜盘
+ if (TimeHelper.GetTime(Clock.Now) > TimeHelper.EndOfDay
+ && TimeHelper.GetTime(Clock.Now) < TimeHelper.BeginOfDay)
+ {
+ DualPosition.ChangeTradingDay();
+ }
+ }
+ else
+ {
+ if (TimeHelper.GetTime(Clock.Now) > TimeHelper.EndOfDay
+ || TimeHelper.GetTime(Clock.Now) < TimeHelper.BeginOfDay)
+ {
+ DualPosition.ChangeTradingDay();
+ }
+ }
+ }
+ }
+
+}
diff --git a/Demo/QuantBox.OQ.Demo/Msic/QQMsg2_code.cs b/Demo/QuantBox.OQ.Demo/Msic/QQMsg2_code.cs
index b59db26..4cab133 100644
--- a/Demo/QuantBox.OQ.Demo/Msic/QQMsg2_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Msic/QQMsg2_code.cs
@@ -1,71 +1,71 @@
-using System;
-
-using OpenQuant.API;
-using System.Windows.Forms;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace QuantBox.OQ.Demo.Msic
-{
- public class QQMsg2_code : Strategy
- {
- public const int WM_PASTE = 0x302;
- public const int WM_KEYDOWN = 0x0100;
- public const int WM_KEYUP = 0x0101;
-
- [DllImport("User32.dll", EntryPoint = "FindWindow")]
- private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
-
- [DllImport("User32.dll", EntryPoint = "PostMessage")]
- public static extern int PostMessage(
- IntPtr hWnd, // 信息发往的窗口的句柄
- int Msg, // 消息ID
- int wParam, // 参数1
- int lParam // 参数2
- );
-
- private string GroupName = "OpenQuant";
- private string textToCopy;
- private IntPtr QQHwndSend = new IntPtr(0);
-
- public override void OnStrategyStart()
- {
- Send("测试剪切板,自动发消息");
- }
-
- private void SetClipboardTextAndSend()
- {
- try
- {
- Clipboard.SetText(textToCopy + "——消息发自OpenQuant");
-
- // 粘贴
- PostMessage(QQHwndSend, WM_PASTE, 0, 0);
- // 按下回车,修改QQ为只按回车就可以发送
- PostMessage(QQHwndSend, WM_KEYDOWN, 13, 0);
- PostMessage(QQHwndSend, WM_KEYUP, 13, 0);
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
- }
-
- private void Send(string msg)
- {
- QQHwndSend = FindWindow("TXGuiFoundation", GroupName);
- if (QQHwndSend.Equals(IntPtr.Zero))
- {
- return;
- }
- // 此句会报错,所以改用另一线程实现
- //Clipboard.SetDataObject("测试剪切板,自动发消息。", true);
-
- textToCopy = msg;
-
- Thread runThread = new Thread(new ThreadStart(SetClipboardTextAndSend));
- runThread.SetApartmentState(ApartmentState.STA);
- runThread.Start();
- }
- }
+using System;
+
+using OpenQuant.API;
+using System.Windows.Forms;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace QuantBox.OQ.Demo.Msic
+{
+ public class QQMsg2_code : Strategy
+ {
+ public const int WM_PASTE = 0x302;
+ public const int WM_KEYDOWN = 0x0100;
+ public const int WM_KEYUP = 0x0101;
+
+ [DllImport("User32.dll", EntryPoint = "FindWindow")]
+ private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
+
+ [DllImport("User32.dll", EntryPoint = "PostMessage")]
+ public static extern int PostMessage(
+ IntPtr hWnd, // 信息发往的窗口的句柄
+ int Msg, // 消息ID
+ int wParam, // 参数1
+ int lParam // 参数2
+ );
+
+ private string GroupName = "OpenQuant";
+ private string textToCopy;
+ private IntPtr QQHwndSend = new IntPtr(0);
+
+ public override void OnStrategyStart()
+ {
+ Send("测试剪切板,自动发消息");
+ }
+
+ private void SetClipboardTextAndSend()
+ {
+ try
+ {
+ Clipboard.SetText(textToCopy + "——消息发自OpenQuant");
+
+ // 粘贴
+ PostMessage(QQHwndSend, WM_PASTE, 0, 0);
+ // 按下回车,修改QQ为只按回车就可以发送
+ PostMessage(QQHwndSend, WM_KEYDOWN, 13, 0);
+ PostMessage(QQHwndSend, WM_KEYUP, 13, 0);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+
+ private void Send(string msg)
+ {
+ QQHwndSend = FindWindow("TXGuiFoundation", GroupName);
+ if (QQHwndSend.Equals(IntPtr.Zero))
+ {
+ return;
+ }
+ // 此句会报错,所以改用另一线程实现
+ //Clipboard.SetDataObject("测试剪切板,自动发消息。", true);
+
+ textToCopy = msg;
+
+ Thread runThread = new Thread(new ThreadStart(SetClipboardTextAndSend));
+ runThread.SetApartmentState(ApartmentState.STA);
+ runThread.Start();
+ }
+ }
}
\ No newline at end of file
diff --git a/Demo/QuantBox.OQ.Demo/Optimization/Matlab2_Scenario.cs b/Demo/QuantBox.OQ.Demo/Optimization/Matlab2_Scenario.cs
index 2a6822d..1bf376f 100644
--- a/Demo/QuantBox.OQ.Demo/Optimization/Matlab2_Scenario.cs
+++ b/Demo/QuantBox.OQ.Demo/Optimization/Matlab2_Scenario.cs
@@ -1,123 +1,123 @@
-using System;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Engine;
-using System.Threading;
-using System.IO;
-
-namespace QuantBox.OQ.Demo.Optimization
-{
- ///
- /// 使用内置的Simple Moving Average Crossover进行演示
- ///
- /// 这个示例的主要目的是为了演示策略与Matlab的互动
- ///
- /// 参考http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=111
- /// 要参加Interop.MLApp引用
- ///
- public class Matlab2_Scenario : Scenario
- {/*
- FileSystemWatcher watcher;
-
- private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
-
- private void WatcherStrat(string path, string filter)
- {
- watcher = new FileSystemWatcher();
- watcher.Path = path;
- watcher.Filter = filter;
-
- watcher.Created += new FileSystemEventHandler(OnProcess);
-
- watcher.EnableRaisingEvents = true;
- }
-
- private void WatcherStop()
- {
- watcher.Created -= new FileSystemEventHandler(OnProcess);
-
- watcher.EnableRaisingEvents = false;
- }
-
- private void OnProcess(object source, FileSystemEventArgs e)
- {
- if (e.ChangeType == WatcherChangeTypes.Created)
- {
- Console.WriteLine("{0},{1}", e.ChangeType, e.FullPath);
- // 运行回测
- Start();
- // 解除等待
- _autoResetEvent.Set();
- }
- }
-
-
- public override void Run()
- {
- MLApp.MLAppClass matlab = new MLApp.MLAppClass();
- matlab.Visible = 1; //会显示Command Window
-
- matlab.Execute("clc; clear all; close all;");
- WatcherStrat(@"D:\test", "*.*");
-
- Project project = Solution.Projects[0];
-
- //int line = 0;
-
- for (int length1 = 3; length1 <= 7; length1++)
- {
- for (int length2 = 3; length2 <= 7; length2++)
- {
- if (length2 > length1)
- {
- // set new parameters
- project.Parameters["Length1"].Value = length1;
- project.Parameters["Length2"].Value = length2;
-
- // print parameters
- Console.Write("Length1 = " + length1 + " Length2 = " + length2);
-
- // start backtest
- // 这句话要写到matlab中的函数中去
- matlab.Execute(@"save D:\test\" + Clock.Now.Ticks);
- // 等待策略跑完一次
- _autoResetEvent.WaitOne();
-
- // calculate objective function
- double objective = Solution.Portfolio.GetValue();
- // print objective
-
- Console.WriteLine(" Objective = " + objective);
- // check best objective
- }
- }
- }
-
- // 执行完后暂时不退出
- //matlab.Quit();
- //matlab = null;
-
- WatcherStop();
- }
- */}
-}
-
-/*
-
-% 从OpenQuant优化过后的结果导出成Excel,然后画参数与绩效的二维图,以下是两个参数的示例
-clc; clear all; close all;
-A=xlsread('模拟退火算法.xlsx','Optimization_History');
-x=A(:,3);y=A(:,4);z=A(:,2);
-t1=linspace(min(x),max(x),max(x)-min(x)); % 如果数据不多,最后的max(x)-min(x)+1可以改成50等
-t2=linspace(min(y),max(y),max(y)-min(y)); % 同上
-[X,Y]=meshgrid(t1,t2);
-Z=griddata(x,y,z,X,Y,'v4');
-figure,surfc(X,Y,Z),colorbar
-xlabel('x');grid on;
-ylabel('y');grid on;
-zlabel('z');grid on;
-title('Performance');
-
-
+using System;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Engine;
+using System.Threading;
+using System.IO;
+
+namespace QuantBox.OQ.Demo.Optimization
+{
+ ///
+ /// 使用内置的Simple Moving Average Crossover进行演示
+ ///
+ /// 这个示例的主要目的是为了演示策略与Matlab的互动
+ ///
+ /// 参考http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=111
+ /// 要参加Interop.MLApp引用
+ ///
+ public class Matlab2_Scenario : Scenario
+ {/*
+ FileSystemWatcher watcher;
+
+ private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
+
+ private void WatcherStrat(string path, string filter)
+ {
+ watcher = new FileSystemWatcher();
+ watcher.Path = path;
+ watcher.Filter = filter;
+
+ watcher.Created += new FileSystemEventHandler(OnProcess);
+
+ watcher.EnableRaisingEvents = true;
+ }
+
+ private void WatcherStop()
+ {
+ watcher.Created -= new FileSystemEventHandler(OnProcess);
+
+ watcher.EnableRaisingEvents = false;
+ }
+
+ private void OnProcess(object source, FileSystemEventArgs e)
+ {
+ if (e.ChangeType == WatcherChangeTypes.Created)
+ {
+ Console.WriteLine("{0},{1}", e.ChangeType, e.FullPath);
+ // 运行回测
+ Start();
+ // 解除等待
+ _autoResetEvent.Set();
+ }
+ }
+
+
+ public override void Run()
+ {
+ MLApp.MLAppClass matlab = new MLApp.MLAppClass();
+ matlab.Visible = 1; //会显示Command Window
+
+ matlab.Execute("clc; clear all; close all;");
+ WatcherStrat(@"D:\test", "*.*");
+
+ Project project = Solution.Projects[0];
+
+ //int line = 0;
+
+ for (int length1 = 3; length1 <= 7; length1++)
+ {
+ for (int length2 = 3; length2 <= 7; length2++)
+ {
+ if (length2 > length1)
+ {
+ // set new parameters
+ project.Parameters["Length1"].Value = length1;
+ project.Parameters["Length2"].Value = length2;
+
+ // print parameters
+ Console.Write("Length1 = " + length1 + " Length2 = " + length2);
+
+ // start backtest
+ // 这句话要写到matlab中的函数中去
+ matlab.Execute(@"save D:\test\" + Clock.Now.Ticks);
+ // 等待策略跑完一次
+ _autoResetEvent.WaitOne();
+
+ // calculate objective function
+ double objective = Solution.Portfolio.GetValue();
+ // print objective
+
+ Console.WriteLine(" Objective = " + objective);
+ // check best objective
+ }
+ }
+ }
+
+ // 执行完后暂时不退出
+ //matlab.Quit();
+ //matlab = null;
+
+ WatcherStop();
+ }
+ */}
+}
+
+/*
+
+% 从OpenQuant优化过后的结果导出成Excel,然后画参数与绩效的二维图,以下是两个参数的示例
+clc; clear all; close all;
+A=xlsread('模拟退火算法.xlsx','Optimization_History');
+x=A(:,3);y=A(:,4);z=A(:,2);
+t1=linspace(min(x),max(x),max(x)-min(x)); % 如果数据不多,最后的max(x)-min(x)+1可以改成50等
+t2=linspace(min(y),max(y),max(y)-min(y)); % 同上
+[X,Y]=meshgrid(t1,t2);
+Z=griddata(x,y,z,X,Y,'v4');
+figure,surfc(X,Y,Z),colorbar
+xlabel('x');grid on;
+ylabel('y');grid on;
+zlabel('z');grid on;
+title('Performance');
+
+
*/
\ No newline at end of file
diff --git a/Demo/QuantBox.OQ.Demo/Optimization/Matlab_Scenario.cs b/Demo/QuantBox.OQ.Demo/Optimization/Matlab_Scenario.cs
index f9c8462..708a566 100644
--- a/Demo/QuantBox.OQ.Demo/Optimization/Matlab_Scenario.cs
+++ b/Demo/QuantBox.OQ.Demo/Optimization/Matlab_Scenario.cs
@@ -1,92 +1,92 @@
-using System;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Engine;
-
-namespace QuantBox.OQ.Demo.Optimization
-{
- ///
- /// 使用内置的Simple Moving Average Crossover进行演示
- ///
- /// 使用Matlab进行3D绩效绘图
- ///
- /// 参考http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=111
- /// 要参加Interop.MLApp引用
- ///
- public class Matlab_Scenario : Scenario
- {/*
- public override void Run()
- {
- MLApp.MLAppClass matlab = new MLApp.MLAppClass();
- matlab.Visible = 1; //会显示Command Window
-
- matlab.Execute("clc; clear all; close all;");
-
- Project project = Solution.Projects[0];
-
- int line = 0;
-
- for (int length1 = 3; length1 <= 7; length1++)
- {
- for (int length2 = 3; length2 <= 7; length2++)
- {
- if (length2 > length1)
- {
- // set new parameters
- project.Parameters["Length1"].Value = length1;
- project.Parameters["Length2"].Value = length2;
-
- // print parameters
- Console.Write("Length1 = " + length1 + " Length2 = " + length2);
-
- // start backtest
- Start();
-
- // calculate objective function
- double objective = Solution.Portfolio.GetValue();
- // print objective
-
- Console.WriteLine(" Objective = " + objective);
- // check best objective
-
- matlab.Execute(string.Format("x({0})={1}; y({0})={2}; z({0})={3};", ++line, length1, length2, objective));
- }
- }
- }
-
- matlab.Execute("t1=linspace(min(x),max(x),max(x)-min(x)+1); %% 如果数据不多,最后的max(x)-min(x)+1可以改成50等");
- matlab.Execute("t2=linspace(min(y),max(y),max(y)-min(y)+1); %% 同上");
- matlab.Execute("[X,Y]=meshgrid(t1,t2);");
- matlab.Execute("Z=griddata(x,y,z,X,Y,'v4');");
- matlab.Execute("figure,surfc(X,Y,Z),colorbar");
- matlab.Execute("xlabel('x'); ylabel('y'); zlabel('z');");
- matlab.Execute("title('Performance');");
-
- matlab.Execute("save"); //保存一下,用于后期分析
-
- // 执行完后暂时不退出
- //matlab.Quit();
- //matlab = null;
- }
- */}
-}
-
-/*
-
-% 从OpenQuant优化过后的结果导出成Excel,然后画参数与绩效的二维图,以下是两个参数的示例
-clc; clear all; close all;
-A=xlsread('模拟退火算法.xlsx','Optimization_History');
-x=A(:,3);y=A(:,4);z=A(:,2);
-t1=linspace(min(x),max(x),max(x)-min(x)); % 如果数据不多,最后的max(x)-min(x)+1可以改成50等
-t2=linspace(min(y),max(y),max(y)-min(y)); % 同上
-[X,Y]=meshgrid(t1,t2);
-Z=griddata(x,y,z,X,Y,'v4');
-figure,surfc(X,Y,Z),colorbar
-xlabel('x');grid on;
-ylabel('y');grid on;
-zlabel('z');grid on;
-title('Performance');
-
-
+using System;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Engine;
+
+namespace QuantBox.OQ.Demo.Optimization
+{
+ ///
+ /// 使用内置的Simple Moving Average Crossover进行演示
+ ///
+ /// 使用Matlab进行3D绩效绘图
+ ///
+ /// 参考http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=111
+ /// 要参加Interop.MLApp引用
+ ///
+ public class Matlab_Scenario : Scenario
+ {/*
+ public override void Run()
+ {
+ MLApp.MLAppClass matlab = new MLApp.MLAppClass();
+ matlab.Visible = 1; //会显示Command Window
+
+ matlab.Execute("clc; clear all; close all;");
+
+ Project project = Solution.Projects[0];
+
+ int line = 0;
+
+ for (int length1 = 3; length1 <= 7; length1++)
+ {
+ for (int length2 = 3; length2 <= 7; length2++)
+ {
+ if (length2 > length1)
+ {
+ // set new parameters
+ project.Parameters["Length1"].Value = length1;
+ project.Parameters["Length2"].Value = length2;
+
+ // print parameters
+ Console.Write("Length1 = " + length1 + " Length2 = " + length2);
+
+ // start backtest
+ Start();
+
+ // calculate objective function
+ double objective = Solution.Portfolio.GetValue();
+ // print objective
+
+ Console.WriteLine(" Objective = " + objective);
+ // check best objective
+
+ matlab.Execute(string.Format("x({0})={1}; y({0})={2}; z({0})={3};", ++line, length1, length2, objective));
+ }
+ }
+ }
+
+ matlab.Execute("t1=linspace(min(x),max(x),max(x)-min(x)+1); %% 如果数据不多,最后的max(x)-min(x)+1可以改成50等");
+ matlab.Execute("t2=linspace(min(y),max(y),max(y)-min(y)+1); %% 同上");
+ matlab.Execute("[X,Y]=meshgrid(t1,t2);");
+ matlab.Execute("Z=griddata(x,y,z,X,Y,'v4');");
+ matlab.Execute("figure,surfc(X,Y,Z),colorbar");
+ matlab.Execute("xlabel('x'); ylabel('y'); zlabel('z');");
+ matlab.Execute("title('Performance');");
+
+ matlab.Execute("save"); //保存一下,用于后期分析
+
+ // 执行完后暂时不退出
+ //matlab.Quit();
+ //matlab = null;
+ }
+ */}
+}
+
+/*
+
+% 从OpenQuant优化过后的结果导出成Excel,然后画参数与绩效的二维图,以下是两个参数的示例
+clc; clear all; close all;
+A=xlsread('模拟退火算法.xlsx','Optimization_History');
+x=A(:,3);y=A(:,4);z=A(:,2);
+t1=linspace(min(x),max(x),max(x)-min(x)); % 如果数据不多,最后的max(x)-min(x)+1可以改成50等
+t2=linspace(min(y),max(y),max(y)-min(y)); % 同上
+[X,Y]=meshgrid(t1,t2);
+Z=griddata(x,y,z,X,Y,'v4');
+figure,surfc(X,Y,Z),colorbar
+xlabel('x');grid on;
+ylabel('y');grid on;
+zlabel('z');grid on;
+title('Performance');
+
+
*/
\ No newline at end of file
diff --git a/Demo/QuantBox.OQ.Demo/Optimization/SharpeRatio_Scenario.cs b/Demo/QuantBox.OQ.Demo/Optimization/SharpeRatio_Scenario.cs
index fef0c2d..a2bde67 100644
--- a/Demo/QuantBox.OQ.Demo/Optimization/SharpeRatio_Scenario.cs
+++ b/Demo/QuantBox.OQ.Demo/Optimization/SharpeRatio_Scenario.cs
@@ -1,80 +1,80 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Engine;
-
-namespace QuantBox.OQ.Demo.Optimization
-{
- ///
- /// 计算率夏普比率
- ///
- public class SharpeRatio_Scenario : Scenario
- {
- public override void Run()
- {
- Start();
-
- //年无风险利率
- double riskFreeRate = 0.03;
- double SR = SharpeRatio(riskFreeRate);
- Console.WriteLine(SR);
- }
-
- public double SharpeRatio(double RiskFreeRate)
- {
- int Days = Solution.Performance.PnLSeries.Count;
- TimeSeries ReturnSeries = new TimeSeries();
- double Portfolio0 = Solution.Cash;
- double Portfolio1;
- for (int t = 0; t < Days; ++t)
- {
- DateTime date = Solution.Performance.PnLSeries.GetDateTime(t);
- Portfolio1 = Solution.Performance.PnLSeries[t] + Portfolio0;
- double DailyReturn = Portfolio1 / Portfolio0 - 1;
- Portfolio0 = Portfolio1;
- ReturnSeries.Add(date, DailyReturn);
- }
-
- double Mean = ReturnSeries.GetMean(0, Days - 1);
- double Std = ReturnSeries.GetStdDev(0, Days - 1);
-
- //年化收益均值、波动率
- Mean = Mean * 250;
- Std = Std * Math.Sqrt(250);
-
- double SR = (Mean - RiskFreeRate) / Std;
- return SR;
- }
- }
-}
-
-/*
-夏普比率公式:
-Sharpe Ratio = (Mean Return - Risk Free Rate)/Volatility
-Mean Return是收益率的均值
-Volatility是收益率的标准差
-Risk Free Rate是无风险利率
-
-使用方法
-1).
-Tools->Options->Memory Management
-将Enable built-in porfolio performance和Enable interval performance update选上,
-然后将Interval length改成86400
-
-2)
-代码
-先得出日收益率序列ReturnSeries,然后求收益率序列的均值、标准差
-
-
-资产组合或者说策略的收益率可以有两种,一是对数收益率,二是简单收益率
-对数收益率 = log( Price(t) / Price(t-1) ) = log(Price(t)) - log(Price(t-1))
-简单收益率 = Price(t) / Price(t-1) - 1
-数学计算时常用对数收益率,因为对数收益率有两个非常好的特性:
-1)一年的日对数收益率之和刚好是年对数收益率,而普通收益率就没有这个特性
-2)此外对数收益率的好处就是涨跌10%对应在价格上是一样的,用简单收益率的话,100元的股票,跌10%变成了90元,再涨10%只能是99元,而不是100元,相反对数收益率就不存在这个问题。
-
-所以很多时候用对数收益率好一些,但是这里其实结果差别不大就后来又用了普通收益率
- */
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Engine;
+
+namespace QuantBox.OQ.Demo.Optimization
+{
+ ///
+ /// 计算率夏普比率
+ ///
+ public class SharpeRatio_Scenario : Scenario
+ {
+ public override void Run()
+ {
+ Start();
+
+ //年无风险利率
+ double riskFreeRate = 0.03;
+ double SR = SharpeRatio(riskFreeRate);
+ Console.WriteLine(SR);
+ }
+
+ public double SharpeRatio(double RiskFreeRate)
+ {
+ int Days = Solution.Performance.PnLSeries.Count;
+ TimeSeries ReturnSeries = new TimeSeries();
+ double Portfolio0 = Solution.Cash;
+ double Portfolio1;
+ for (int t = 0; t < Days; ++t)
+ {
+ DateTime date = Solution.Performance.PnLSeries.GetDateTime(t);
+ Portfolio1 = Solution.Performance.PnLSeries[t] + Portfolio0;
+ double DailyReturn = Portfolio1 / Portfolio0 - 1;
+ Portfolio0 = Portfolio1;
+ ReturnSeries.Add(date, DailyReturn);
+ }
+
+ double Mean = ReturnSeries.GetMean(0, Days - 1);
+ double Std = ReturnSeries.GetStdDev(0, Days - 1);
+
+ //年化收益均值、波动率
+ Mean = Mean * 250;
+ Std = Std * Math.Sqrt(250);
+
+ double SR = (Mean - RiskFreeRate) / Std;
+ return SR;
+ }
+ }
+}
+
+/*
+夏普比率公式:
+Sharpe Ratio = (Mean Return - Risk Free Rate)/Volatility
+Mean Return是收益率的均值
+Volatility是收益率的标准差
+Risk Free Rate是无风险利率
+
+使用方法
+1).
+Tools->Options->Memory Management
+将Enable built-in porfolio performance和Enable interval performance update选上,
+然后将Interval length改成86400
+
+2)
+代码
+先得出日收益率序列ReturnSeries,然后求收益率序列的均值、标准差
+
+
+资产组合或者说策略的收益率可以有两种,一是对数收益率,二是简单收益率
+对数收益率 = log( Price(t) / Price(t-1) ) = log(Price(t)) - log(Price(t-1))
+简单收益率 = Price(t) / Price(t-1) - 1
+数学计算时常用对数收益率,因为对数收益率有两个非常好的特性:
+1)一年的日对数收益率之和刚好是年对数收益率,而普通收益率就没有这个特性
+2)此外对数收益率的好处就是涨跌10%对应在价格上是一样的,用简单收益率的话,100元的股票,跌10%变成了90元,再涨10%只能是99元,而不是100元,相反对数收益率就不存在这个问题。
+
+所以很多时候用对数收益率好一些,但是这里其实结果差别不大就后来又用了普通收益率
+ */
diff --git a/Demo/QuantBox.OQ.Demo/Plugins_Functions/CTP_code.cs b/Demo/QuantBox.OQ.Demo/Plugins_Functions/CTP_code.cs
index 2d4f16f..7bdffc0 100644
--- a/Demo/QuantBox.OQ.Demo/Plugins_Functions/CTP_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Plugins_Functions/CTP_code.cs
@@ -1,135 +1,135 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-
-using QuantBox.Helper.CTP;
-using QuantBox.CSharp2CTP;
-
-namespace QuantBox.OQ.Demo.Plugins_Functions
-{
- ///
- /// 取合约、行情、保证金率与手续费
- /// 订阅深度行情、交易所状态
- ///
- /// OnRspQryDepthMarketData:查一次,返回一次。通过交易接口。没有订阅的可以返回
- /// OnRtnDepthMarketData:是总是返回。通过行情接口。只能返回订阅过的。
- /// 这个事件在最后触发,优先级循序为:Trade\Quote\MarketDepth\OnRtnDepthMarketData
- ///
- /// 要使用OnRtnDepthMarketData,请将插件属性中的EmitOnRtnDepthMarketData改成True
- ///
- public class CTP_code:Strategy
- {
- public override void OnStrategyStart()
- {
- CTPAPI.GetInstance().OnRspQryInstrument += new CTPAPI.RspQryInstrument(OnRspQryInstrument);
- CTPAPI.GetInstance().OnRspQryInstrumentMarginRate += new CTPAPI.RspQryInstrumentMarginRate(OnRspQryInstrumentMarginRate);
- CTPAPI.GetInstance().OnRspQryInstrumentCommissionRate += new CTPAPI.RspQryInstrumentCommissionRate(OnRspQryInstrumentCommissionRate);
- // 交易所状态
- CTPAPI.GetInstance().OnRtnInstrumentStatus += new CTPAPI.RtnInstrumentStatus(OnRtnInstrumentStatus);
-
- CTPAPI.GetInstance().OnRspQryTradingAccount += new CTPAPI.RspQryTradingAccount(OnRspQryTradingAccount);
-
- CTPAPI.GetInstance().OnRspReqQryInvestorPosition += new CTPAPI.RspReqQryInvestorPosition(OnRspReqQryInvestorPosition);
-
- // 此方法已经过期,在插件3.8.2.0中开始废弃
- //CTPAPI.GetInstance().OnRtnDepthMarketData += new CTPAPI.RtnDepthMarketData(OnRtnDepthMarketData);
- }
-
- void OnRspReqQryInvestorPosition(CThostFtdcInvestorPositionField pInvestorPosition)
- {
- Console.WriteLine("==持仓");
- Console.WriteLine(pInvestorPosition.InstrumentID);
- }
-
- void OnRspQryTradingAccount(CThostFtdcTradingAccountField pTradingAccount)
- {
- Console.WriteLine("==资金");
- Console.WriteLine(pTradingAccount.Balance);
- Console.WriteLine(pTradingAccount.TradingDay);
- }
-
- public override void OnStrategyStop()
- {
- CTPAPI.GetInstance().OnRspQryInstrument -= new CTPAPI.RspQryInstrument(OnRspQryInstrument);
- CTPAPI.GetInstance().OnRspQryInstrumentMarginRate -= new CTPAPI.RspQryInstrumentMarginRate(OnRspQryInstrumentMarginRate);
- CTPAPI.GetInstance().OnRspQryInstrumentCommissionRate -= new CTPAPI.RspQryInstrumentCommissionRate(OnRspQryInstrumentCommissionRate);
-
- CTPAPI.GetInstance().OnRtnInstrumentStatus -= new CTPAPI.RtnInstrumentStatus(OnRtnInstrumentStatus);
-
- CTPAPI.GetInstance().OnRspQryTradingAccount -= new CTPAPI.RspQryTradingAccount(OnRspQryTradingAccount);
-
- // 此方法已经过期,在插件3.8.2.0中开始废弃
- //CTPAPI.GetInstance().OnRtnDepthMarketData -= new CTPAPI.RtnDepthMarketData(OnRtnDepthMarketData);
- }
-
- public override void OnBar(Bar bar)
- {
- //以下四句只是演示,实盘中请保存查询出来的结果,并且一天只查一次
- CTPAPI.GetInstance().ReqQryInstrument("IF1312");
-
- // 一定得加上TThostFtdcHedgeFlagType
- CTPAPI.GetInstance().ReqQryInstrumentMarginRate("IF1312", TThostFtdcHedgeFlagType.Speculation);
-
- //目前模拟平台目前查询没有返回,实盘时返回的是产品的手续费,如查"IF1312",返回的是"IF"
- CTPAPI.GetInstance().ReqQryInstrumentCommissionRate("IF1312");
-
- //通过交易接口查询,主要用来取涨跌停或没有直接订阅的行情
- CTPAPI.GetInstance().ReqQryDepthMarketData("IF1309");
- }
-
- void OnRspQryInstrumentMarginRate(CThostFtdcInstrumentMarginRateField pInstrumentMarginRate)
- {
- Console.WriteLine("==保证金率");
- Console.WriteLine(pInstrumentMarginRate.InstrumentID);
- Console.WriteLine(pInstrumentMarginRate.LongMarginRatioByMoney);
- Console.WriteLine(pInstrumentMarginRate.LongMarginRatioByVolume);
- Console.WriteLine(pInstrumentMarginRate.ShortMarginRatioByMoney);
- Console.WriteLine(pInstrumentMarginRate.ShortMarginRatioByVolume);
- }
-
- void OnRspQryInstrument(CThostFtdcInstrumentField pInstrument)
- {
- Console.WriteLine("==合约列表");
- Console.WriteLine(pInstrument.LongMarginRatio);
- Console.WriteLine(pInstrument.ShortMarginRatio);
- }
-
- void OnRspQryInstrumentCommissionRate(CThostFtdcInstrumentCommissionRateField pInstrumentCommissionRate)
- {
- Console.WriteLine("==手续费率");
- Console.WriteLine(pInstrumentCommissionRate.CloseRatioByMoney);
- Console.WriteLine(pInstrumentCommissionRate.CloseRatioByVolume);
- }
-
- void OnRtnInstrumentStatus(CThostFtdcInstrumentStatusField pInstrumentStatus)
- {
- // 由于只在有新消息过来时才会收到,所以可能认为不好测试,看不出效果
- // 在测试时,把插件属性的ResumeType改成THOST_TERT_RESTART,然后连接CTP就可以看到效果了。
- Console.WriteLine("==交易所状态");
- Console.WriteLine("{0},{1},{2}",
- pInstrumentStatus.ExchangeID, pInstrumentStatus.InstrumentID,
- pInstrumentStatus.InstrumentStatus);
- }
-
- //void OnRspQryDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData)
- //{
- // Console.WriteLine("==取深度行情");
- // Console.WriteLine(pDepthMarketData.InstrumentID);
- // Console.WriteLine(pDepthMarketData.LastPrice);
- // Console.WriteLine(pDepthMarketData.UpperLimitPrice);
- // Console.WriteLine(pDepthMarketData.LowerLimitPrice);
- //}
-
- void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData)
- {
- // 得打开EmitOnRtnDepthMarketData开关
- Console.WriteLine("++订阅深度行情");
- Console.WriteLine(pDepthMarketData.InstrumentID);
- Console.WriteLine(pDepthMarketData.LastPrice);
- Console.WriteLine(pDepthMarketData.OpenInterest);
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+
+using QuantBox.Helper.CTP;
+using QuantBox.CSharp2CTP;
+
+namespace QuantBox.OQ.Demo.Plugins_Functions
+{
+ ///
+ /// 取合约、行情、保证金率与手续费
+ /// 订阅深度行情、交易所状态
+ ///
+ /// OnRspQryDepthMarketData:查一次,返回一次。通过交易接口。没有订阅的可以返回
+ /// OnRtnDepthMarketData:是总是返回。通过行情接口。只能返回订阅过的。
+ /// 这个事件在最后触发,优先级循序为:Trade\Quote\MarketDepth\OnRtnDepthMarketData
+ ///
+ /// 要使用OnRtnDepthMarketData,请将插件属性中的EmitOnRtnDepthMarketData改成True
+ ///
+ public class CTP_code:Strategy
+ {
+ public override void OnStrategyStart()
+ {
+ CTPAPI.GetInstance().OnRspQryInstrument += new CTPAPI.RspQryInstrument(OnRspQryInstrument);
+ CTPAPI.GetInstance().OnRspQryInstrumentMarginRate += new CTPAPI.RspQryInstrumentMarginRate(OnRspQryInstrumentMarginRate);
+ CTPAPI.GetInstance().OnRspQryInstrumentCommissionRate += new CTPAPI.RspQryInstrumentCommissionRate(OnRspQryInstrumentCommissionRate);
+ // 交易所状态
+ CTPAPI.GetInstance().OnRtnInstrumentStatus += new CTPAPI.RtnInstrumentStatus(OnRtnInstrumentStatus);
+
+ CTPAPI.GetInstance().OnRspQryTradingAccount += new CTPAPI.RspQryTradingAccount(OnRspQryTradingAccount);
+
+ CTPAPI.GetInstance().OnRspReqQryInvestorPosition += new CTPAPI.RspReqQryInvestorPosition(OnRspReqQryInvestorPosition);
+
+ // 此方法已经过期,在插件3.8.2.0中开始废弃
+ //CTPAPI.GetInstance().OnRtnDepthMarketData += new CTPAPI.RtnDepthMarketData(OnRtnDepthMarketData);
+ }
+
+ void OnRspReqQryInvestorPosition(CThostFtdcInvestorPositionField pInvestorPosition)
+ {
+ Console.WriteLine("==持仓");
+ Console.WriteLine(pInvestorPosition.InstrumentID);
+ }
+
+ void OnRspQryTradingAccount(CThostFtdcTradingAccountField pTradingAccount)
+ {
+ Console.WriteLine("==资金");
+ Console.WriteLine(pTradingAccount.Balance);
+ Console.WriteLine(pTradingAccount.TradingDay);
+ }
+
+ public override void OnStrategyStop()
+ {
+ CTPAPI.GetInstance().OnRspQryInstrument -= new CTPAPI.RspQryInstrument(OnRspQryInstrument);
+ CTPAPI.GetInstance().OnRspQryInstrumentMarginRate -= new CTPAPI.RspQryInstrumentMarginRate(OnRspQryInstrumentMarginRate);
+ CTPAPI.GetInstance().OnRspQryInstrumentCommissionRate -= new CTPAPI.RspQryInstrumentCommissionRate(OnRspQryInstrumentCommissionRate);
+
+ CTPAPI.GetInstance().OnRtnInstrumentStatus -= new CTPAPI.RtnInstrumentStatus(OnRtnInstrumentStatus);
+
+ CTPAPI.GetInstance().OnRspQryTradingAccount -= new CTPAPI.RspQryTradingAccount(OnRspQryTradingAccount);
+
+ // 此方法已经过期,在插件3.8.2.0中开始废弃
+ //CTPAPI.GetInstance().OnRtnDepthMarketData -= new CTPAPI.RtnDepthMarketData(OnRtnDepthMarketData);
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ //以下四句只是演示,实盘中请保存查询出来的结果,并且一天只查一次
+ CTPAPI.GetInstance().ReqQryInstrument("IF1312");
+
+ // 一定得加上TThostFtdcHedgeFlagType
+ CTPAPI.GetInstance().ReqQryInstrumentMarginRate("IF1312", TThostFtdcHedgeFlagType.Speculation);
+
+ //目前模拟平台目前查询没有返回,实盘时返回的是产品的手续费,如查"IF1312",返回的是"IF"
+ CTPAPI.GetInstance().ReqQryInstrumentCommissionRate("IF1312");
+
+ //通过交易接口查询,主要用来取涨跌停或没有直接订阅的行情
+ CTPAPI.GetInstance().ReqQryDepthMarketData("IF1309");
+ }
+
+ void OnRspQryInstrumentMarginRate(CThostFtdcInstrumentMarginRateField pInstrumentMarginRate)
+ {
+ Console.WriteLine("==保证金率");
+ Console.WriteLine(pInstrumentMarginRate.InstrumentID);
+ Console.WriteLine(pInstrumentMarginRate.LongMarginRatioByMoney);
+ Console.WriteLine(pInstrumentMarginRate.LongMarginRatioByVolume);
+ Console.WriteLine(pInstrumentMarginRate.ShortMarginRatioByMoney);
+ Console.WriteLine(pInstrumentMarginRate.ShortMarginRatioByVolume);
+ }
+
+ void OnRspQryInstrument(CThostFtdcInstrumentField pInstrument)
+ {
+ Console.WriteLine("==合约列表");
+ Console.WriteLine(pInstrument.LongMarginRatio);
+ Console.WriteLine(pInstrument.ShortMarginRatio);
+ }
+
+ void OnRspQryInstrumentCommissionRate(CThostFtdcInstrumentCommissionRateField pInstrumentCommissionRate)
+ {
+ Console.WriteLine("==手续费率");
+ Console.WriteLine(pInstrumentCommissionRate.CloseRatioByMoney);
+ Console.WriteLine(pInstrumentCommissionRate.CloseRatioByVolume);
+ }
+
+ void OnRtnInstrumentStatus(CThostFtdcInstrumentStatusField pInstrumentStatus)
+ {
+ // 由于只在有新消息过来时才会收到,所以可能认为不好测试,看不出效果
+ // 在测试时,把插件属性的ResumeType改成THOST_TERT_RESTART,然后连接CTP就可以看到效果了。
+ Console.WriteLine("==交易所状态");
+ Console.WriteLine("{0},{1},{2}",
+ pInstrumentStatus.ExchangeID, pInstrumentStatus.InstrumentID,
+ pInstrumentStatus.InstrumentStatus);
+ }
+
+ //void OnRspQryDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData)
+ //{
+ // Console.WriteLine("==取深度行情");
+ // Console.WriteLine(pDepthMarketData.InstrumentID);
+ // Console.WriteLine(pDepthMarketData.LastPrice);
+ // Console.WriteLine(pDepthMarketData.UpperLimitPrice);
+ // Console.WriteLine(pDepthMarketData.LowerLimitPrice);
+ //}
+
+ void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData)
+ {
+ // 得打开EmitOnRtnDepthMarketData开关
+ Console.WriteLine("++订阅深度行情");
+ Console.WriteLine(pDepthMarketData.InstrumentID);
+ Console.WriteLine(pDepthMarketData.LastPrice);
+ Console.WriteLine(pDepthMarketData.OpenInterest);
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/QuantBox.OQ.Demo.csproj b/Demo/QuantBox.OQ.Demo/QuantBox.OQ.Demo.csproj
index 8ea490f..27265b1 100644
--- a/Demo/QuantBox.OQ.Demo/QuantBox.OQ.Demo.csproj
+++ b/Demo/QuantBox.OQ.Demo/QuantBox.OQ.Demo.csproj
@@ -20,6 +20,7 @@
DEBUG;TRACE
prompt
4
+ x86
pdbonly
@@ -43,15 +44,15 @@
False
- ..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.CSharp2CTP.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.CSharp2CTP.dll
False
- ..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.Helper.CTP.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.Helper.CTP.dll
-
+
False
- ..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.OQ.Extensions.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.OQ.Extensions.dll
diff --git a/Demo/QuantBox.OQ.Demo/QuantBox.OQ.Demo.csproj.user b/Demo/QuantBox.OQ.Demo/QuantBox.OQ.Demo.csproj.user
new file mode 100644
index 0000000..497396c
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo/QuantBox.OQ.Demo.csproj.user
@@ -0,0 +1,10 @@
+
+
+
+ D:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\;D:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\
+
+
+ Program
+ D:\Program Files %28x86%29\SmartQuant Ltd\OpenQuant\OpenQuant.exe
+
+
\ No newline at end of file
diff --git a/Demo/QuantBox.OQ.Demo/Scenarios/PortfolioPersistent_code.cs b/Demo/QuantBox.OQ.Demo/Scenarios/PortfolioPersistent_code.cs
index 9b8c140..1c12314 100644
--- a/Demo/QuantBox.OQ.Demo/Scenarios/PortfolioPersistent_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Scenarios/PortfolioPersistent_code.cs
@@ -1,93 +1,93 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using System.Xml.Serialization;
-using System.IO;
-
-namespace QuantBox.OQ.Demo.Scenarios
-{
- public class PortfolioPersistent_code : Strategy
- {
- ///
- /// 持仓组合持久化
- ///
- /// 按 策略_合约.xml 进行保存,用户可以自己编辑此文件
- ///
- public override void OnStrategyStart()
- {
- LoadPosition();
- }
-
- public override void OnStrategyStop()
- {
- SavePosition();
- }
-
- private void LoadPosition()
- {
- MyPosition pos = new MyPosition();
- XmlSerializer serializer = new XmlSerializer(pos.GetType());
-
- string path = string.Format("{0}_{1}.xml", Name, Instrument);
-
- try
- {
- using (FileStream stream = new FileStream(path, FileMode.Open))
- {
- pos = (MyPosition)serializer.Deserialize(stream);
- stream.Close();
-
- if (pos.Amount != 0)
- {
- Portfolio.Add(pos.EntryDate, pos.Amount > 0 ? TransactionSide.Buy : TransactionSide.Sell,
- Math.Abs(pos.Amount), Instrument, pos.Price, "从XML中初始化");
- }
-
- Console.WriteLine(string.Format("加载路径:{0},持仓:{1},价格:{2}", path,pos.Amount,pos.Price));
- }
- }
- catch(Exception ex)
- {
- Console.WriteLine(ex);
- }
- }
-
- private void SavePosition()
- {
- MyPosition pos = new MyPosition();
- XmlSerializer serializer = new XmlSerializer(pos.GetType());
-
- string path = string.Format("{0}_{1}.xml", Name, Instrument);
- using (TextWriter writer = new StreamWriter(path))
- {
- if (null == Position)
- {
- pos.EntryDate = Clock.Now;
- pos.Amount = 0;
- pos.Price = 0;
- }
- else
- {
- pos.EntryDate = Position.EntryDate;
- pos.Amount = Position.Amount;
- pos.Price = Position.GetPrice();
- }
-
- serializer.Serialize(writer, pos);
- writer.Close();
-
- Console.WriteLine(string.Format("保存路径:{0},持仓:{1},价格:{2}", path, pos.Amount, pos.Price));
- }
- }
- }
-}
-
-public class MyPosition
-{
- public DateTime EntryDate;
- public double Amount;
- public double Price;
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using System.Xml.Serialization;
+using System.IO;
+
+namespace QuantBox.OQ.Demo.Scenarios
+{
+ public class PortfolioPersistent_code : Strategy
+ {
+ ///
+ /// 持仓组合持久化
+ ///
+ /// 按 策略_合约.xml 进行保存,用户可以自己编辑此文件
+ ///
+ public override void OnStrategyStart()
+ {
+ LoadPosition();
+ }
+
+ public override void OnStrategyStop()
+ {
+ SavePosition();
+ }
+
+ private void LoadPosition()
+ {
+ MyPosition pos = new MyPosition();
+ XmlSerializer serializer = new XmlSerializer(pos.GetType());
+
+ string path = string.Format("{0}_{1}.xml", Name, Instrument);
+
+ try
+ {
+ using (FileStream stream = new FileStream(path, FileMode.Open))
+ {
+ pos = (MyPosition)serializer.Deserialize(stream);
+ stream.Close();
+
+ if (pos.Amount != 0)
+ {
+ Portfolio.Add(pos.EntryDate, pos.Amount > 0 ? TransactionSide.Buy : TransactionSide.Sell,
+ Math.Abs(pos.Amount), Instrument, pos.Price, "从XML中初始化");
+ }
+
+ Console.WriteLine(string.Format("加载路径:{0},持仓:{1},价格:{2}", path,pos.Amount,pos.Price));
+ }
+ }
+ catch(Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
+ }
+
+ private void SavePosition()
+ {
+ MyPosition pos = new MyPosition();
+ XmlSerializer serializer = new XmlSerializer(pos.GetType());
+
+ string path = string.Format("{0}_{1}.xml", Name, Instrument);
+ using (TextWriter writer = new StreamWriter(path))
+ {
+ if (null == Position)
+ {
+ pos.EntryDate = Clock.Now;
+ pos.Amount = 0;
+ pos.Price = 0;
+ }
+ else
+ {
+ pos.EntryDate = Position.EntryDate;
+ pos.Amount = Position.Amount;
+ pos.Price = Position.GetPrice();
+ }
+
+ serializer.Serialize(writer, pos);
+ writer.Close();
+
+ Console.WriteLine(string.Format("保存路径:{0},持仓:{1},价格:{2}", path, pos.Amount, pos.Price));
+ }
+ }
+ }
+}
+
+public class MyPosition
+{
+ public DateTime EntryDate;
+ public double Amount;
+ public double Price;
+}
diff --git a/Demo/QuantBox.OQ.Demo/StopStrategy/Comfirm_code.cs b/Demo/QuantBox.OQ.Demo/StopStrategy/Comfirm_code.cs
index 725eab2..4faee86 100644
--- a/Demo/QuantBox.OQ.Demo/StopStrategy/Comfirm_code.cs
+++ b/Demo/QuantBox.OQ.Demo/StopStrategy/Comfirm_code.cs
@@ -1,47 +1,47 @@
-using System;
-using System.Drawing;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-
-namespace QuantBox.OQ.Demo.StopStrategy
-{
- public class MyStrategy : Strategy
- {
- bool bStopStrategy = false;
- public override void OnStrategyStart()
- {
- DialogResult dr = MessageBox.Show("是否停止?", "确认", MessageBoxButtons.OKCancel);
- if (dr == DialogResult.OK)
- {
- //1.直接停止。其实写在这并不能停止策略
- //StopStrategy();
-
- //2.使用定时器,3秒后停止
- AddTimer(Clock.Now.AddSeconds(3));
-
- //3.使用变量,在策略运行的地方停止
- //bStopStrategy = true;
- }
- }
-
- public override void OnTimer(DateTime datetime, Object data)
- {
- Console.WriteLine("OnTimer");
- StopStrategy();
- }
-
- public override void OnBar(Bar bar)
- {
- if (bStopStrategy)
- {
- Console.WriteLine("OnBar");
- StopStrategy();
- }
-
- Console.WriteLine(bar);
- }
-
- }
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+
+namespace QuantBox.OQ.Demo.StopStrategy
+{
+ public class MyStrategy : Strategy
+ {
+ bool bStopStrategy = false;
+ public override void OnStrategyStart()
+ {
+ DialogResult dr = MessageBox.Show("是否停止?", "确认", MessageBoxButtons.OKCancel);
+ if (dr == DialogResult.OK)
+ {
+ //1.直接停止。其实写在这并不能停止策略
+ //StopStrategy();
+
+ //2.使用定时器,3秒后停止
+ AddTimer(Clock.Now.AddSeconds(3));
+
+ //3.使用变量,在策略运行的地方停止
+ //bStopStrategy = true;
+ }
+ }
+
+ public override void OnTimer(DateTime datetime, Object data)
+ {
+ Console.WriteLine("OnTimer");
+ StopStrategy();
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ if (bStopStrategy)
+ {
+ Console.WriteLine("OnBar");
+ StopStrategy();
+ }
+
+ Console.WriteLine(bar);
+ }
+
+ }
}
\ No newline at end of file
diff --git a/Demo/QuantBox.OQ.Demo/StopStrategy/Form_code.cs b/Demo/QuantBox.OQ.Demo/StopStrategy/Form_code.cs
index e774779..27b0c7f 100644
--- a/Demo/QuantBox.OQ.Demo/StopStrategy/Form_code.cs
+++ b/Demo/QuantBox.OQ.Demo/StopStrategy/Form_code.cs
@@ -1,64 +1,64 @@
-using System;
-using System.Drawing;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-
-namespace QuantBox.OQ.Demo.StopStrategy
-{
- public class Form1 : Form
- {
- public bool bStopStrategy = false;
- public Button button1;
- public Form1()
- {
- button1 = new Button();
- button1.Size = new Size(40, 40);
- button1.Location = new Point(30, 30);
- button1.Text = "Click me";
- this.Controls.Add(button1);
- button1.Click += new EventHandler(button1_Click);
- }
- private void button1_Click(object sender, EventArgs e)
- {
- MessageBox.Show("Hello World");
- bStopStrategy = true;
- }
- }
-
- ///
- /// 弹出窗口,在窗口上点击按钮后停止
- ///
- /// 或在User Commands中停止
- ///
- public class Form_code:Strategy
- {
- private Form1 test;
-
- public override void OnStrategyStart()
- {
- test = new Form1();
- System.Threading.ThreadPool.QueueUserWorkItem(delegate(object state)
- {
- Application.Run(test);
- });
- }
-
- public override void OnBar(Bar bar)
- {
- if (test.bStopStrategy)
- {
- Console.WriteLine("OnBar");
- StopStrategy();
- }
-
- Console.WriteLine(bar);
- }
-
- public override void OnUserCommand(UserCommand command)
- {
- StopStrategy();
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+
+namespace QuantBox.OQ.Demo.StopStrategy
+{
+ public class Form1 : Form
+ {
+ public bool bStopStrategy = false;
+ public Button button1;
+ public Form1()
+ {
+ button1 = new Button();
+ button1.Size = new Size(40, 40);
+ button1.Location = new Point(30, 30);
+ button1.Text = "Click me";
+ this.Controls.Add(button1);
+ button1.Click += new EventHandler(button1_Click);
+ }
+ private void button1_Click(object sender, EventArgs e)
+ {
+ MessageBox.Show("Hello World");
+ bStopStrategy = true;
+ }
+ }
+
+ ///
+ /// 弹出窗口,在窗口上点击按钮后停止
+ ///
+ /// 或在User Commands中停止
+ ///
+ public class Form_code:Strategy
+ {
+ private Form1 test;
+
+ public override void OnStrategyStart()
+ {
+ test = new Form1();
+ System.Threading.ThreadPool.QueueUserWorkItem(delegate(object state)
+ {
+ Application.Run(test);
+ });
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ if (test.bStopStrategy)
+ {
+ Console.WriteLine("OnBar");
+ StopStrategy();
+ }
+
+ Console.WriteLine(bar);
+ }
+
+ public override void OnUserCommand(UserCommand command)
+ {
+ StopStrategy();
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/StopStrategy/LimitAccount_code.cs b/Demo/QuantBox.OQ.Demo/StopStrategy/LimitAccount_code.cs
index 10ad0ee..d2cf553 100644
--- a/Demo/QuantBox.OQ.Demo/StopStrategy/LimitAccount_code.cs
+++ b/Demo/QuantBox.OQ.Demo/StopStrategy/LimitAccount_code.cs
@@ -1,35 +1,35 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-namespace QuantBox.OQ.Demo.StopStrategy
-{
- ///
- /// 限制指定账号使用
- ///
- public class LimitAccount_code : Strategy
- {
- bool CheckAccount()
- {
- BrokerInfo bi = DataManager.GetBrokerInfo();
- return bi.Accounts[0].Name.CompareTo("你的账号") == 0;
- }
-
- public override void OnPositionOpened()
- {
- if (!CheckAccount())
- StopStrategy();
- }
-
- public override void OnBar(Bar bar)
- {
- if (!CheckAccount())
- StopStrategy();
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+namespace QuantBox.OQ.Demo.StopStrategy
+{
+ ///
+ /// 限制指定账号使用
+ ///
+ public class LimitAccount_code : Strategy
+ {
+ bool CheckAccount()
+ {
+ BrokerInfo bi = DataManager.GetBrokerInfo();
+ return bi.Accounts[0].Name.CompareTo("你的账号") == 0;
+ }
+
+ public override void OnPositionOpened()
+ {
+ if (!CheckAccount())
+ StopStrategy();
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ if (!CheckAccount())
+ StopStrategy();
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Strategys/DoubleMA_Crossover_code.cs b/Demo/QuantBox.OQ.Demo/Strategys/DoubleMA_Crossover_code.cs
index c8a4a09..06bbce0 100644
--- a/Demo/QuantBox.OQ.Demo/Strategys/DoubleMA_Crossover_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Strategys/DoubleMA_Crossover_code.cs
@@ -1,131 +1,134 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using QuantBox.OQ.Demo.Module;
-using QuantBox.OQ.Demo.Helper;
-
-namespace QuantBox.OQ.Demo.Strategys
-{
- ///
- /// 双均线策略
- ///
- /// 设置的是3分钟
- ///
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=113
- ///
- public class DoubleMA_Crossover_code : TargetPositionModule
- {
- [OptimizationParameter(5, 10, 1)]
- [Parameter("快均线", "SMA")]
- int fastLength = 5;
-
- [OptimizationParameter(11, 15, 1)]
- [Parameter("慢均线", "SMA")]
- int slowLength = 12;
-
- [Parameter("交易手数")]
- double Qty = 1;
-
- [Parameter("时间周期,请按自己的设置修改")]
- int BarSize = 180;
-
- SMA fastSMA;
- SMA slowSMA;
-
- static BrokerInfo BrokerInfo;
-
- void LoadHistoricalBars(DateTime datetime)
- {
- DateTime dtEnd = datetime;
- DateTime dtBegin = dtEnd.AddDays(-5);//这个时间按自己的需求修改
-
- TradeSeries ts = DataManager.GetHistoricalTrades(Instrument, dtBegin, dtEnd);
- //个人认为这个地方应当过滤下Trade数据,去除无效的再转换成Bars
- BarSeries bs = DataManager.CompressBars(ts, BarType.Time, BarSize);
- BarSeries barsMin = GetBars(BarType.Time, BarSize);
- foreach (Bar b in bs)
- {
- barsMin.Add(b);
- }
- }
-
- public override void OnStrategyStart()
- {
- base.OnStrategyStart();
-
- // 测试用,自定义交易时间,仿真或实盘时可删除
- base.TimeHelper = new TimeHelper(new int[] { 0, 2400 },2100, 1458);
-
- base.TargetPosition = 0;
- //base.DualPosition.Long.Qty = 0;
- //base.DualPosition.Long.QtyToday = 0;
- //base.DualPosition.Short.Qty = 0;
- //base.DualPosition.Short.QtyToday = 0;
- if(BrokerInfo == null)
- {
- // 使用静态的主要原因是每个实例都来取一次没有必要
- BrokerInfo = DataManager.GetBrokerInfo();
- }
- if (BrokerInfo.Accounts.Count > 0)
- {
- BrokerAccount brokerAccount = BrokerInfo.Accounts[0];
- GetBrokerInfoHelper.Transform(brokerAccount, base.DualPosition);
- }
-
-
- LoadHistoricalBars(Clock.Now);
-
- BarSeries bars1min = GetBars(BarType.Time, BarSize);
-
- fastSMA = new SMA(bars1min, fastLength, Color.Red);
- slowSMA = new SMA(bars1min, slowLength, Color.Green);
-
- Draw(fastSMA, 0);
- Draw(slowSMA, 0);
- }
-
- public override void OnBar(Bar bar)
- {
- Cross cross = fastSMA.Crosses(slowSMA, bar);
- if (Cross.Above == cross)
- {
- base.TargetPosition = 1;
- TextParameter.Text = "金叉";
- }
- else if (Cross.Below == cross)
- {
- base.TargetPosition = -1;
- TextParameter.Text = "死叉";
- }
- else
- {
- // 保持上次的状态
- }
-
- base.ChangeTradingDay();
-
- base.OnBar(bar);
- }
-
- public override void OnTrade(Trade trade)
- {
- do
- {
- // 尾盘平仓
- if (0 != ExitOnClose(90,""))
- break;
-
- // 跟踪止损
- TrailingStop(trade.Price, 5, StopMode.Absolute, "");
-
- } while (false);
-
- base.OnTrade(trade);
- }
- }
-
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using QuantBox.OQ.Demo.Module;
+using QuantBox.OQ.Demo.Helper;
+
+namespace QuantBox.OQ.Demo.Strategys
+{
+ ///
+ /// 双均线策略
+ ///
+ /// 设置的是3分钟
+ ///
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=113
+ ///
+ public class DoubleMA_Crossover_code : TargetPositionModule
+ {
+ [OptimizationParameter(5, 10, 1)]
+ [Parameter("快均线", "SMA")]
+ int fastLength = 5;
+
+ [OptimizationParameter(11, 15, 1)]
+ [Parameter("慢均线", "SMA")]
+ int slowLength = 12;
+
+ [Parameter("交易手数")]
+ double Qty = 1;
+
+ [Parameter("时间周期,请按自己的设置修改")]
+ int BarSize = 60;
+
+ SMA fastSMA;
+ SMA slowSMA;
+
+ static BrokerInfo BrokerInfo;
+
+ void LoadHistoricalBars(DateTime datetime)
+ {
+ DateTime dtEnd = datetime;
+ DateTime dtBegin = dtEnd.AddDays(-5);//这个时间按自己的需求修改
+
+ TradeSeries ts = DataManager.GetHistoricalTrades(Instrument, dtBegin, dtEnd);//获取历史交易数据
+ //个人认为这个地方应当过滤下Trade数据,去除无效的再转换成Bars
+ BarSeries bs = DataManager.CompressBars(ts, BarType.Time, BarSize);
+ BarSeries barsMin = GetBars(BarType.Time, BarSize);
+ foreach (Bar b in bs)
+ {
+ barsMin.Add(b);
+ }
+ }
+
+ public override void OnStrategyStart()
+ {
+ base.OnStrategyStart();//开始基类策略
+
+ // 测试用,自定义交易时间,仿真或实盘时可删除
+ base.TimeHelper = new TimeHelper(new int[] { 0, 2400 },2100, 1458);
+
+ base.TargetPosition = 0;
+ //base.DualPosition.Long.Qty = 0;
+ //base.DualPosition.Long.QtyToday = 0;
+ //base.DualPosition.Short.Qty = 0;
+ //base.DualPosition.Short.QtyToday = 0;
+ if(BrokerInfo == null)
+ {
+ // 使用静态的主要原因是每个实例都来取一次没有必要
+ BrokerInfo = DataManager.GetBrokerInfo();
+ }
+ if (BrokerInfo.Accounts.Count > 0)
+ {
+ BrokerAccount brokerAccount = BrokerInfo.Accounts[0];//表示一组代理账户的属性,如名称、BuyingPower和位置列表。
+ GetBrokerInfoHelper.Transform(brokerAccount, base.DualPosition);
+ }
+
+
+ LoadHistoricalBars(Clock.Now);
+
+ BarSeries bars1min = GetBars(BarType.Time, BarSize);
+
+ fastSMA = new SMA(bars1min, fastLength, Color.Red);
+ slowSMA = new SMA(bars1min, slowLength, Color.Green);
+
+ Draw(fastSMA, 0);
+ Draw(slowSMA, 0);
+ }
+ ///
+ /// OnBar事件
+ ///
+ ///
+ public override void OnBar(Bar bar)
+ {
+ Cross cross = fastSMA.Crosses(slowSMA, bar);
+ if (Cross.Above == cross)
+ {
+ base.TargetPosition = 1;
+ TextParameter.Text = "金叉";
+ }
+ else if (Cross.Below == cross)
+ {
+ base.TargetPosition = -1;
+ TextParameter.Text = "死叉";
+ }
+ else
+ {
+ // 保持上次的状态
+ }
+
+ base.ChangeTradingDay();
+
+ base.OnBar(bar);
+ }
+
+ public override void OnTrade(Trade trade)
+ {
+ do
+ {
+ // 尾盘平仓
+ if (0 != ExitOnClose(90,""))
+ break;
+
+ // 跟踪止损
+ TrailingStop(trade.Price, 5, StopMode.Absolute, "");
+
+ } while (false);
+
+ base.OnTrade(trade);
+ }
+ }
+
+}
diff --git a/Demo/QuantBox.OQ.Demo/Strategys/DrawCircles_code.cs b/Demo/QuantBox.OQ.Demo/Strategys/DrawCircles_code.cs
index 695e3a5..7eb69e7 100644
--- a/Demo/QuantBox.OQ.Demo/Strategys/DrawCircles_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Strategys/DrawCircles_code.cs
@@ -1,35 +1,35 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-namespace QuantBox.OQ.Demo.Strategys
-{
- ///
- /// 在K线上将每天的第一个K线上画点,标记出来
- ///
- public class DrawCircles_code : Strategy
- {
- int day = -1;
- public TimeSeries ts = new TimeSeries();
-
- public override void OnStrategyStart()
- {
- ts.Width = 5;
- Draw(ts, 0, DrawStyle.Circles);
- }
-
- public override void OnBar(Bar bar)
- {
- if (bar.DateTime.Day != day)
- {
- day = bar.DateTime.Day;
- ts.Add(bar.DateTime, bar.High + 1);
- }
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+namespace QuantBox.OQ.Demo.Strategys
+{
+ ///
+ /// 在K线上将每天的第一个K线上画点,标记出来
+ ///
+ public class DrawCircles_code : Strategy
+ {
+ int day = -1;
+ public TimeSeries ts = new TimeSeries();
+
+ public override void OnStrategyStart()
+ {
+ ts.Width = 5;
+ Draw(ts, 0, DrawStyle.Circles);
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ if (bar.DateTime.Day != day)
+ {
+ day = bar.DateTime.Day;//获取bqr序列的日期
+ ts.Add(bar.DateTime, bar.High + 1);
+ }
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Strategys/DualThrust_OpenRange_code.cs b/Demo/QuantBox.OQ.Demo/Strategys/DualThrust_OpenRange_code.cs
index 0eae679..d80c364 100644
--- a/Demo/QuantBox.OQ.Demo/Strategys/DualThrust_OpenRange_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Strategys/DualThrust_OpenRange_code.cs
@@ -1,196 +1,196 @@
-using System;
-using System.Drawing;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-using QuantBox.OQ.Demo.Indicator;
-using QuantBox.OQ.Demo.Module;
-using QuantBox.OQ.Demo.Helper;
-
-namespace QuantBox.OQ.Demo.Strategys
-{
- ///
- /// Dual Thrust & Open Range Break
- ///
- /// 添加日线,添加1分钟线
- /// 在属性面板中设置策略类型,是DualThrust还是OpenRangeBreak.
- /// 当设置成OpenRangeBreak时,N设置无效
- ///
- /// 没有历史数据加载的部分,请参考论坛上提到的从模拟切换到实盘的方法
- ///
- /// 网上对这两个策略的配图
- /// http://gzqh.cnfol.com/111101/175,1787,11039812,00.shtml
- /// 论坛上DualThrust的TB版源码
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=195
- /// 论坛上OpenRangeBreak中文描述
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=398
- ///
- public class DualThrust_OpenRange_code : TargetPositionModule
- {
- public enum StrategyType
- {
- DualThrust,
- OpenRangeBreak,
- }
-
- [Parameter]
- StrategyType strategyType = StrategyType.DualThrust;
- [OptimizationParameter(0.4, 0.9, 0.1)]
- [Parameter("K1,上轨的参数")]
- double K1 = 0.5;
- [OptimizationParameter(0.4, 0.9, 0.1)]
- [Parameter("K2,下轨的参数")]
- double K2 = 0.5;
- [Parameter]
- double Range = 10;
- [Parameter]
- int N = 5;
- [Parameter]
- double Qty = 1;
-
- TimeSeries UpSeries;
- TimeSeries DownSeries;
- TimeSeries RangeSeries;
-
- PC HH;
- PC HC;
- PC LC;
- PC LL;
-
- double UpLine = double.NaN;
- double DownLine = double.NaN;
-
- BarSeries bars86400;
-
- public override void OnStrategyStart()
- {
- base.OnStrategyStart();
-
- // 测试用,自定义交易时间,仿真或实盘时可删除
- base.TimeHelper = new TimeHelper(new int[] { 0, 2400 },2100, 1458);
-
- base.TargetPosition = 0;
- base.DualPosition.Long.Qty = 0;
- base.DualPosition.Short.Qty = 0;
-
- UpSeries = new TimeSeries("Up");
- DownSeries = new TimeSeries("Down");
- RangeSeries = new TimeSeries("Range");
-
- int n = N;
- if (StrategyType.OpenRangeBreak == strategyType)
- {
- n = 1;
- }
-
- bars86400 = GetBars(BarType.Time, 86400);
- HH = new PC(bars86400, n, BarData.High, PC.CalcType.Max, PC.UseLast.Yes);
- HC = new PC(bars86400, n, BarData.Close, PC.CalcType.Max, PC.UseLast.Yes);
- LC = new PC(bars86400, n, BarData.Close, PC.CalcType.Min, PC.UseLast.Yes);
- LL = new PC(bars86400, n, BarData.Low, PC.CalcType.Min, PC.UseLast.Yes);
-
-
- Draw(UpSeries, 0);
- Draw(DownSeries, 0);
- Draw(RangeSeries, 2);
- }
-
- public override void OnBarOpen(Bar bar)
- {
- do
- {
- if (86400 == bar.Size)
- {
- if (HH.Count < 1)
- break;
-
- if (StrategyType.OpenRangeBreak == strategyType)
- {
- Range = HH.Last - LL.Last;
- }
- else
- {
- Range = Math.Max(HH.Last - LC.Last, HC.Last - LL.Last);
- }
-
- double dbOpen = bar.Open;
- // 如果昨天波动过小,调整一下最小range
- Range = Math.Max(Range, dbOpen * 0.01 * 0.2);
-
- UpLine = dbOpen + K1 * Range;
- DownLine = dbOpen - K2 * Range;
-
- base.ChangeTradingDay();
- }
- } while (false);
-
- base.OnBarOpen(bar);
- }
-
- public override void OnBar(Bar bar)
- {
- do
- {
- // 尾盘平仓
- if (0 != ExitOnClose(60,""))
- break;
-
- // 日线数据上不处理
- if (86400 == bar.Size)
- break;
-
- // 数据
- if (double.IsNaN(UpLine))
- break;
-
- UpSeries.Add(bar.DateTime, UpLine);
- DownSeries.Add(bar.DateTime, DownLine);
- RangeSeries.Add(bar.DateTime, Range);
-
- if (bar.Close > UpLine)
- {
- TargetPosition = 1;
- TextParameter.Text = "突破上轨,多头";
- }
- else if (bar.Close < DownLine)
- {
- TargetPosition = -1;
- TextParameter.Text = "突破下轨,空头";
- }
- else
- {
- // 处于中间状态的怎么处理?
- }
- }
- while (false);
-
- if (Mode == StrategyMode.Simulation)
- {
- // 从模拟切换实盘时用
- //return;
- }
-
- base.OnBar(bar);
- }
-
-
- public override void OnTrade(Trade trade)
- {
- do
- {
- // 尾盘平仓
- if (0 != ExitOnClose(300,""))
- break;
-
- // 跟踪止损
- TrailingStop(trade.Price, 5, StopMode.Absolute, "");
-
- } while (false);
-
-
- base.OnTrade(trade);
- }
- }
-}
+using System;
+using System.Drawing;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+using QuantBox.OQ.Demo.Indicator;
+using QuantBox.OQ.Demo.Module;
+using QuantBox.OQ.Demo.Helper;
+
+namespace QuantBox.OQ.Demo.Strategys
+{
+ ///
+ /// Dual Thrust & Open Range Break
+ ///
+ /// 添加日线,添加1分钟线
+ /// 在属性面板中设置策略类型,是DualThrust还是OpenRangeBreak.
+ /// 当设置成OpenRangeBreak时,N设置无效
+ ///
+ /// 没有历史数据加载的部分,请参考论坛上提到的从模拟切换到实盘的方法
+ ///
+ /// 网上对这两个策略的配图
+ /// http://gzqh.cnfol.com/111101/175,1787,11039812,00.shtml
+ /// 论坛上DualThrust的TB版源码
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=195
+ /// 论坛上OpenRangeBreak中文描述
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=398
+ ///
+ public class DualThrust_OpenRange_code : TargetPositionModule
+ {
+ public enum StrategyType
+ {
+ DualThrust,
+ OpenRangeBreak,
+ }
+
+ [Parameter]
+ StrategyType strategyType = StrategyType.DualThrust;
+ [OptimizationParameter(0.4, 0.9, 0.1)]
+ [Parameter("K1,上轨的参数")]
+ double K1 = 0.5;
+ [OptimizationParameter(0.4, 0.9, 0.1)]
+ [Parameter("K2,下轨的参数")]
+ double K2 = 0.5;
+ [Parameter]
+ double Range = 10;
+ [Parameter]
+ int N = 5;
+ [Parameter]
+ double Qty = 1;
+
+ TimeSeries UpSeries;
+ TimeSeries DownSeries;
+ TimeSeries RangeSeries;
+
+ PC HH;
+ PC HC;
+ PC LC;
+ PC LL;
+
+ double UpLine = double.NaN;
+ double DownLine = double.NaN;
+
+ BarSeries bars86400;
+
+ public override void OnStrategyStart()
+ {
+ base.OnStrategyStart();
+
+ // 测试用,自定义交易时间,仿真或实盘时可删除
+ base.TimeHelper = new TimeHelper(new int[] { 0, 2400 },2100, 1458);
+
+ base.TargetPosition = 0;
+ base.DualPosition.Long.Qty = 0;
+ base.DualPosition.Short.Qty = 0;
+
+ UpSeries = new TimeSeries("Up");
+ DownSeries = new TimeSeries("Down");
+ RangeSeries = new TimeSeries("Range");
+
+ int n = N;
+ if (StrategyType.OpenRangeBreak == strategyType)
+ {
+ n = 1;
+ }
+
+ bars86400 = GetBars(BarType.Time, 86400);
+ HH = new PC(bars86400, n, BarData.High, PC.CalcType.Max, PC.UseLast.Yes);
+ HC = new PC(bars86400, n, BarData.Close, PC.CalcType.Max, PC.UseLast.Yes);
+ LC = new PC(bars86400, n, BarData.Close, PC.CalcType.Min, PC.UseLast.Yes);
+ LL = new PC(bars86400, n, BarData.Low, PC.CalcType.Min, PC.UseLast.Yes);
+
+
+ Draw(UpSeries, 0);
+ Draw(DownSeries, 0);
+ Draw(RangeSeries, 2);
+ }
+
+ public override void OnBarOpen(Bar bar)
+ {
+ do
+ {
+ if (86400 == bar.Size)
+ {
+ if (HH.Count < 1)
+ break;
+
+ if (StrategyType.OpenRangeBreak == strategyType)
+ {
+ Range = HH.Last - LL.Last;
+ }
+ else
+ {
+ Range = Math.Max(HH.Last - LC.Last, HC.Last - LL.Last);
+ }
+
+ double dbOpen = bar.Open;
+ // 如果昨天波动过小,调整一下最小range
+ Range = Math.Max(Range, dbOpen * 0.01 * 0.2);
+
+ UpLine = dbOpen + K1 * Range;
+ DownLine = dbOpen - K2 * Range;
+
+ base.ChangeTradingDay();
+ }
+ } while (false);
+
+ base.OnBarOpen(bar);
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ do
+ {
+ // 尾盘平仓
+ if (0 != ExitOnClose(60,""))
+ break;
+
+ // 日线数据上不处理
+ if (86400 == bar.Size)
+ break;
+
+ // 数据
+ if (double.IsNaN(UpLine))
+ break;
+
+ UpSeries.Add(bar.DateTime, UpLine);
+ DownSeries.Add(bar.DateTime, DownLine);
+ RangeSeries.Add(bar.DateTime, Range);
+
+ if (bar.Close > UpLine)
+ {
+ TargetPosition = 1;
+ TextParameter.Text = "突破上轨,多头";
+ }
+ else if (bar.Close < DownLine)
+ {
+ TargetPosition = -1;
+ TextParameter.Text = "突破下轨,空头";
+ }
+ else
+ {
+ // 处于中间状态的怎么处理?
+ }
+ }
+ while (false);
+
+ if (Mode == StrategyMode.Simulation)
+ {
+ // 从模拟切换实盘时用
+ //return;
+ }
+
+ base.OnBar(bar);
+ }
+
+
+ public override void OnTrade(Trade trade)
+ {
+ do
+ {
+ // 尾盘平仓
+ if (0 != ExitOnClose(300,""))
+ break;
+
+ // 跟踪止损
+ TrailingStop(trade.Price, 5, StopMode.Absolute, "");
+
+ } while (false);
+
+
+ base.OnTrade(trade);
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Strategys/DynamicBreakOut2_code.cs b/Demo/QuantBox.OQ.Demo/Strategys/DynamicBreakOut2_code.cs
index 0ce213d..8bd320c 100644
--- a/Demo/QuantBox.OQ.Demo/Strategys/DynamicBreakOut2_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Strategys/DynamicBreakOut2_code.cs
@@ -1,151 +1,151 @@
-using System;
-using System.Drawing;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-
-using QuantBox.OQ.Demo.Indicator;
-using QuantBox.OQ.Demo.Module;
-using QuantBox.OQ.Demo.Helper;
-
-namespace QuantBox.OQ.Demo.Strategys
-{
- ///
- /// 自适应动态突破系统
- ///
- /// 添加一个日线,再添加一个1分钟
- ///
- /// 论坛上的TB代码
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=193
- /// 网上的TS代码
- /// http://www.programtrading.tw/viewtopic.php?t=504
- ///
- public class DynamicBreakOut2_code : TargetPositionModule
- {
- [Parameter("指标窗口长度(LookBackDays)的上限")]
- int ceilingAmt = 60;
- [Parameter("指标窗口长度(LookBackDays)的下限")]
- int floorAmt = 20;
- [Parameter("布林线参数")]
- double bolBandTrig = 2;
- [Parameter("合约数目")]
- double Qty = 1;
-
- // 指标窗口长度(LookBackDays)的初始值
- int lookBackDays = 20;
-
- SMD smd30;
- LookBackDays lbd;
- DynamicBBU dbbu;
-
- BarSeries bars86400;
-
- TimeSeries upBandSeries;
- TimeSeries dnBandSeries;
- TimeSeries buyPointSeries;
- TimeSeries sellPointSeries;
-
- public override void OnStrategyStart()
- {
- base.OnStrategyStart();
-
- // 测试用,自定义交易时间,仿真或实盘时可删除
- base.TimeHelper = new TimeHelper(new int[] { 0, 2400 }, 2100, 1458);
-
- base.TargetPosition = 0;
- base.DualPosition.Long.Qty = 0;
- base.DualPosition.Short.Qty = 0;
-
- bars86400 = GetBars(BarType.Time, 86400);
-
- smd30 = new SMD(bars86400, 30);
- lbd = new LookBackDays(smd30, lookBackDays, floorAmt, ceilingAmt);
- dbbu = new DynamicBBU(lbd, bars86400, bolBandTrig, BarData.Close);
-
- Draw(smd30, 2);
- Draw(lbd, 3);
- Draw(dbbu.SMA, 0);
- Draw(dbbu.BBL, 0);
- Draw(dbbu, 0);
-
- upBandSeries = new TimeSeries("upBandSeries");
- dnBandSeries = new TimeSeries("dnBandSeries");
- buyPointSeries = new TimeSeries("buyPointSeries");
- sellPointSeries = new TimeSeries("sellPointSeries");
-
- upBandSeries.Color = Color.Red;
- dnBandSeries.Color = Color.Red;
-
- Draw(upBandSeries, 0);
- Draw(dnBandSeries, 0);
- Draw(buyPointSeries, 0);
- Draw(sellPointSeries, 0);
-
- base.OnStrategyStart();
- }
-
- public override void OnBar(Bar bar)
- {
- if (bar.Size == 86400)
- {
- base.ChangeTradingDay();
- return;
- }
-
- if (lbd.Count < 1 || dbbu.Count < 1)
- return;
-
- int lookBackDaysInt = (int)lbd.Last;
- int nEnd = bars86400.Count - 1;
- int nBegin = nEnd - lookBackDays + 1;
-
- double buyPoint = bars86400.HighestHigh(nBegin, nEnd);
- double sellPoint = bars86400.LowestLow(nBegin, nEnd);
- double longLiqPoint = dbbu.SMA.Last;
- double shortLiqPoint = dbbu.SMA.Last;
- double upBand = dbbu.Last;
- double dnBand = dbbu.BBL.Last;
-
- upBandSeries.Add(bar.DateTime, upBand);
- dnBandSeries.Add(bar.DateTime, dnBand);
- buyPointSeries.Add(bar.DateTime, buyPoint);
- sellPointSeries.Add(bar.DateTime, sellPoint);
-
- do
- {
- if (GetCurrentQty()>0)
- {
- if (bar.Close < longLiqPoint)
- {
- TargetPosition = 0;
- TextParameter.Text = "低于多头流动点";
- }
- }
- else if (GetCurrentQty() < 0)
- {
- if (bar.Close > shortLiqPoint)
- {
- TargetPosition = 0;
- TextParameter.Text = "高于空头流动点";
- }
- }
- else
- {
- if (bar.Close > upBand)
- {
- TargetPosition = 1;
- TextParameter.Text = "突破上轨开仓";
- }
- else if (bar.Close < dnBand)
- {
- TargetPosition = -1;
- TextParameter.Text = "突破下轨开仓";
- }
- }
- } while (false);
-
- base.OnBar(bar);
- }
- }
-}
+using System;
+using System.Drawing;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+
+using QuantBox.OQ.Demo.Indicator;
+using QuantBox.OQ.Demo.Module;
+using QuantBox.OQ.Demo.Helper;
+
+namespace QuantBox.OQ.Demo.Strategys
+{
+ ///
+ /// 自适应动态突破系统
+ ///
+ /// 添加一个日线,再添加一个1分钟
+ ///
+ /// 论坛上的TB代码
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=193
+ /// 网上的TS代码
+ /// http://www.programtrading.tw/viewtopic.php?t=504
+ ///
+ public class DynamicBreakOut2_code : TargetPositionModule
+ {
+ [Parameter("指标窗口长度(LookBackDays)的上限")]
+ int ceilingAmt = 60;
+ [Parameter("指标窗口长度(LookBackDays)的下限")]
+ int floorAmt = 20;
+ [Parameter("布林线参数")]
+ double bolBandTrig = 2;
+ [Parameter("合约数目")]
+ double Qty = 1;
+
+ // 指标窗口长度(LookBackDays)的初始值
+ int lookBackDays = 20;
+
+ SMD smd30;
+ LookBackDays lbd;
+ DynamicBBU dbbu;
+
+ BarSeries bars86400;
+
+ TimeSeries upBandSeries;
+ TimeSeries dnBandSeries;
+ TimeSeries buyPointSeries;
+ TimeSeries sellPointSeries;
+
+ public override void OnStrategyStart()
+ {
+ base.OnStrategyStart();
+
+ // 测试用,自定义交易时间,仿真或实盘时可删除
+ base.TimeHelper = new TimeHelper(new int[] { 0, 2400 }, 2100, 1458);
+
+ base.TargetPosition = 0;
+ base.DualPosition.Long.Qty = 0;
+ base.DualPosition.Short.Qty = 0;
+
+ bars86400 = GetBars(BarType.Time, 86400);
+
+ smd30 = new SMD(bars86400, 30);
+ lbd = new LookBackDays(smd30, lookBackDays, floorAmt, ceilingAmt);
+ dbbu = new DynamicBBU(lbd, bars86400, bolBandTrig, BarData.Close);
+
+ Draw(smd30, 2);
+ Draw(lbd, 3);
+ Draw(dbbu.SMA, 0);
+ Draw(dbbu.BBL, 0);
+ Draw(dbbu, 0);
+
+ upBandSeries = new TimeSeries("upBandSeries");
+ dnBandSeries = new TimeSeries("dnBandSeries");
+ buyPointSeries = new TimeSeries("buyPointSeries");
+ sellPointSeries = new TimeSeries("sellPointSeries");
+
+ upBandSeries.Color = Color.Red;
+ dnBandSeries.Color = Color.Red;
+
+ Draw(upBandSeries, 0);
+ Draw(dnBandSeries, 0);
+ Draw(buyPointSeries, 0);
+ Draw(sellPointSeries, 0);
+
+ base.OnStrategyStart();
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ if (bar.Size == 86400)
+ {
+ base.ChangeTradingDay();
+ return;
+ }
+
+ if (lbd.Count < 1 || dbbu.Count < 1)
+ return;
+
+ int lookBackDaysInt = (int)lbd.Last;
+ int nEnd = bars86400.Count - 1;
+ int nBegin = nEnd - lookBackDays + 1;
+
+ double buyPoint = bars86400.HighestHigh(nBegin, nEnd);
+ double sellPoint = bars86400.LowestLow(nBegin, nEnd);
+ double longLiqPoint = dbbu.SMA.Last;
+ double shortLiqPoint = dbbu.SMA.Last;
+ double upBand = dbbu.Last;
+ double dnBand = dbbu.BBL.Last;
+
+ upBandSeries.Add(bar.DateTime, upBand);
+ dnBandSeries.Add(bar.DateTime, dnBand);
+ buyPointSeries.Add(bar.DateTime, buyPoint);
+ sellPointSeries.Add(bar.DateTime, sellPoint);
+
+ do
+ {
+ if (GetCurrentQty()>0)
+ {
+ if (bar.Close < longLiqPoint)
+ {
+ TargetPosition = 0;
+ TextParameter.Text = "低于多头流动点";
+ }
+ }
+ else if (GetCurrentQty() < 0)
+ {
+ if (bar.Close > shortLiqPoint)
+ {
+ TargetPosition = 0;
+ TextParameter.Text = "高于空头流动点";
+ }
+ }
+ else
+ {
+ if (bar.Close > upBand)
+ {
+ TargetPosition = 1;
+ TextParameter.Text = "突破上轨开仓";
+ }
+ else if (bar.Close < dnBand)
+ {
+ TargetPosition = -1;
+ TextParameter.Text = "突破下轨开仓";
+ }
+ }
+ } while (false);
+
+ base.OnBar(bar);
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Strategys/PairTrading2_code.cs b/Demo/QuantBox.OQ.Demo/Strategys/PairTrading2_code.cs
index 643d6bf..0388044 100644
--- a/Demo/QuantBox.OQ.Demo/Strategys/PairTrading2_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Strategys/PairTrading2_code.cs
@@ -33,7 +33,7 @@ public class PairTrading2_code : TargetPositionModule
// 直接使用这种static比使用Global要快
static PairTrading2_code S1;
static PairTrading2_code S2;
-
+
public override void OnStrategyStart()
{
base.OnStrategyStart();
diff --git a/Demo/QuantBox.OQ.Demo/Strategys/PairTrading_code.cs b/Demo/QuantBox.OQ.Demo/Strategys/PairTrading_code.cs
index 0bdc9dc..56012e2 100644
--- a/Demo/QuantBox.OQ.Demo/Strategys/PairTrading_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Strategys/PairTrading_code.cs
@@ -1,107 +1,107 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-using System.Collections.Generic;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-
-namespace QuantBox.OQ.Demo.Strategys
-{
- ///
- /// 配对交易示例
- /// 主要靠静态变量来实现引用两个合约的数据,并计算价差。
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=345
- ///
- /// 现在已经不推荐使用此方法,请参考MySpreadMarketData.cs
- ///
- public class PairTrading_code:Strategy
- {
- Instrument Instrument1 = InstrumentManager.Instruments["cu000"];
- Instrument Instrument2 = InstrumentManager.Instruments["zn000"];
-
- //static PairTrading_code Strategy1;
- //static PairTrading_code Strategy2;
- static BarSeries BarSeries1;
- static BarSeries BarSeries2;
-
- static TimeSeries spreadSeries;
-
- static Dictionary _bars;
-
- [Parameter("两合约价格序列回归方程的系数")]
- double Slope = 4.325347;
-
- [Parameter("两合约价格序列回归方程的常数项")]
- double Const = -8358.336;
-
- [Parameter("时间窗口")]
- int Length = 100;
-
- int barSize = 60;
-
- SMA sma;
-
- public override void OnStrategyStart()
- {
- if (Instrument1 == Instrument)
- {
- //Strategy1 = this;
- BarSeries1 = GetBars(BarType.Time, barSize);
- }
- else if (Instrument2 == Instrument)
- {
- //Strategy2 = this;
- BarSeries2 = GetBars(BarType.Time, barSize);
- }
- else
- {
- Console.WriteLine("合约错误!" + Instrument);
- }
-
- spreadSeries = new TimeSeries("spread");
- _bars = new Dictionary();
- sma = new SMA(spreadSeries, Length);
-
- Draw(spreadSeries, 2);
- Draw(sma, 2);
- }
-
- double Calculate(Bar bar1, Bar bar2)
- {
- return Calculate(bar1.Close,bar2.Close);
- }
-
- double Calculate(double db1, double db2)
- {
- return db1 - db2 * Slope - Const;
- }
-
- public override void OnBar(Bar bar)
- {
- _bars[Instrument.Symbol] = bar.Close;
-
- }
-
- public override void OnBarSlice(long size)
- {
- if (Instrument1 == Instrument)
- return;
-
- double b1, b2;
- if (_bars.TryGetValue("cu000", out b1)
- && _bars.TryGetValue("zn000", out b2))
- {
- spreadSeries.Add(Clock.Now, Calculate(b1, b2));
- }
-
- if (sma.Count < 1)
- return;
-
- //操作
- //Sell(Instrument2,Qty2,"O|卖开");
- //Buy(Instrument1,Qty1,"O|买开");
- }
- }
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+
+namespace QuantBox.OQ.Demo.Strategys
+{
+ ///
+ /// 配对交易示例
+ /// 主要靠静态变量来实现引用两个合约的数据,并计算价差。
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=345
+ ///
+ /// 现在已经不推荐使用此方法,请参考MySpreadMarketData.cs
+ ///
+ public class PairTrading_code:Strategy
+ {
+ Instrument Instrument1 = InstrumentManager.Instruments["cu000"];
+ Instrument Instrument2 = InstrumentManager.Instruments["zn000"];
+
+ //static PairTrading_code Strategy1;
+ //static PairTrading_code Strategy2;
+ static BarSeries BarSeries1;
+ static BarSeries BarSeries2;
+
+ static TimeSeries spreadSeries;
+
+ static Dictionary _bars;
+
+ [Parameter("两合约价格序列回归方程的系数")]
+ double Slope = 4.325347;
+
+ [Parameter("两合约价格序列回归方程的常数项")]
+ double Const = -8358.336;
+
+ [Parameter("时间窗口")]
+ int Length = 100;
+
+ int barSize = 60;
+
+ SMA sma;
+
+ public override void OnStrategyStart()
+ {
+ if (Instrument1 == Instrument)
+ {
+ //Strategy1 = this;
+ BarSeries1 = GetBars(BarType.Time, barSize);
+ }
+ else if (Instrument2 == Instrument)
+ {
+ //Strategy2 = this;
+ BarSeries2 = GetBars(BarType.Time, barSize);
+ }
+ else
+ {
+ Console.WriteLine("合约错误!" + Instrument);
+ }
+
+ spreadSeries = new TimeSeries("spread");
+ _bars = new Dictionary();
+ sma = new SMA(spreadSeries, Length);
+
+ Draw(spreadSeries, 2);
+ Draw(sma, 2);
+ }
+
+ double Calculate(Bar bar1, Bar bar2)
+ {
+ return Calculate(bar1.Close,bar2.Close);
+ }
+
+ double Calculate(double db1, double db2)
+ {
+ return db1 - db2 * Slope - Const;
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ _bars[Instrument.Symbol] = bar.Close;
+
+ }
+
+ public override void OnBarSlice(long size)
+ {
+ if (Instrument1 == Instrument)
+ return;
+
+ double b1, b2;
+ if (_bars.TryGetValue("cu000", out b1)
+ && _bars.TryGetValue("zn000", out b2))
+ {
+ spreadSeries.Add(Clock.Now, Calculate(b1, b2));
+ }
+
+ if (sma.Count < 1)
+ return;
+
+ //操作
+ //Sell(Instrument2,Qty2,"O|卖开");
+ //Buy(Instrument1,Qty1,"O|买开");
+ }
+ }
+}
diff --git a/Demo/QuantBox.OQ.Demo/Strategys/RBreaker_code.cs b/Demo/QuantBox.OQ.Demo/Strategys/RBreaker_code.cs
index 3e6c9b2..9ecb0d3 100644
--- a/Demo/QuantBox.OQ.Demo/Strategys/RBreaker_code.cs
+++ b/Demo/QuantBox.OQ.Demo/Strategys/RBreaker_code.cs
@@ -1,251 +1,256 @@
-using System;
-using System.Drawing;
-using System.Reflection;
-using System.Windows.Forms;
-
-using OpenQuant.API;
-using OpenQuant.API.Indicators;
-using OpenQuant.API.Plugins;
-using QuantBox.OQ.Demo.Module;
-using QuantBox.OQ.Demo.Helper;
-
-namespace QuantBox.OQ.Demo.Strategys
-{
- ///
- /// R-Breaker
- ///
- /// 使用方法,添加一个日线,添加一个1分钟线
- /// 将第一天前一天的收盘、最高、最低填好
- /// 由于历史的收高低是手工填写的,所以整个代码中没有加载历史数据的代码,
- /// 如果想长期无人值守,只要在点运行前改正好上一交易日的收高低即可
- ///
- /// 网上金字塔版,带图
- /// http://www.yafco.com/show.php?contentid=261740
- /// 论坛上的TB版
- /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=194
- ///
- public class RBreaker_code : TargetPositionModule
- {
- //第一次运行时,前一天的开高底收
- [Parameter("前一天最高价", "PreDay")]
- double preDayHigh = 0;
- [Parameter("前一天最低价", "PreDay")]
- double preDayLow = 0;
- [Parameter("前一天收盘价", "PreDay")]
- double preDayClose = 0;
-
- [OptimizationParameter(0.3, 0.5, 0.05)]
- [Parameter]
- double f1 = 0.35;
- [Parameter]
- [OptimizationParameter(0.05, 0.09, 0.01)]
- double f2 = 0.07;
- [Parameter]
- [OptimizationParameter(0.10, 0.15, 0.01)]
- double f3 = 0.12;
- [Parameter]
- double Qty = 1;
-
- double reverse = 0.5;
- double rangemin = 0.2;
- double xdiv = 3;
-
- double div = 3;
- double i_reverse = 1;
- double i_rangemin = 1;
- bool rfilter;
-
- TimeSeries S1;
- TimeSeries B1;
-
- long barSize = long.MaxValue;
-
- #region R-Breaker
- TimeSeries ssetup;
- TimeSeries bsetup;
- TimeSeries senter;
- TimeSeries benter;
- TimeSeries bbreak;
- TimeSeries sbreak;
-
- double _ssetup = double.NaN;
- double _bsetup = double.NaN;
- double _senter = double.NaN;
- double _benter = double.NaN;
- double _bbreak = double.NaN;
- double _sbreak = double.NaN;
-
- void UpdateAtDaily_RBreaker(Bar bar)
- {
- preDayHigh = bar.High;
- preDayLow = bar.Low;
- preDayClose = bar.Close;
-
- Update6Line();
- }
-
- void Update6Line()
- {
- //先计算,时候到了再放到序列中
- _ssetup = preDayHigh + f1 * (preDayClose - preDayLow);
- _bsetup = preDayLow - f1 * (preDayHigh - preDayClose);
-
- _senter = (1 + f2) / 2.0 * (preDayHigh + preDayClose) - f2 * preDayLow;
- _benter = (1 + f2) / 2.0 * (preDayLow + preDayClose) - f2 * preDayHigh;
-
- _bbreak = _ssetup + f3 * (_ssetup - _bsetup);
- _sbreak = _bsetup - f3 * (_ssetup - _bsetup);
- }
-
- void UpdateAtBar_RBreaker(Bar bar)
- {
- ssetup.Add(bar.DateTime, _ssetup);
- bsetup.Add(bar.DateTime, _bsetup);
- senter.Add(bar.DateTime, _senter);
- benter.Add(bar.DateTime, _benter);
- bbreak.Add(bar.DateTime, _bbreak);
- sbreak.Add(bar.DateTime, _sbreak);
- }
- #endregion
-
- #region HighLow
- double HighToday = double.MinValue;
- double LowToday = double.MaxValue;
- void UpdateAtDaily_HighLow(Bar bar)
- {
- HighToday = double.MinValue;
- LowToday = double.MaxValue;
- }
- void UpdateAtBar_HighLow(Bar bar)
- {
-
- HighToday = Math.Max(HighToday, bar.High);
- LowToday = Math.Min(LowToday, bar.Low);
- }
- #endregion
-
- public override void OnStrategyStart()
- {
- base.OnStrategyStart();
-
- // 测试用,自定义交易时间,仿真或实盘时可删除
- base.TimeHelper = new TimeHelper(new int[] { 0, 2400 }, 2100, 1458);
-
- base.TargetPosition = 0;
- base.DualPosition.Long.Qty = 0;
- base.DualPosition.Short.Qty = 0;
-
- // 自动得到当时时间窗口大小
- foreach (BarRequest barRequest in DataRequests.BarRequests)
- {
- barSize = Math.Min(barSize, barRequest.BarSize);
- }
- Console.WriteLine("barSize = {0}", barSize);
-
- Update6Line();
-
- ssetup = new TimeSeries("观察卖出价", Color.Green);
- bsetup = new TimeSeries("观察买入价", Color.Green);
- bbreak = new TimeSeries("突破买入价", Color.Red);
- sbreak = new TimeSeries("突破卖出价", Color.Red);
- senter = new TimeSeries("反转卖出价", Color.Black);
- benter = new TimeSeries("反转买入价", Color.Black);
-
- S1 = new TimeSeries("S1", Color.Blue);
- B1 = new TimeSeries("B1", Color.Blue);
-
- Draw(ssetup, 0);
- Draw(bsetup, 0);
- Draw(bbreak, 0);
- Draw(sbreak, 0);
- Draw(senter, 0);
- Draw(benter, 0);
-
- Draw(S1, 0);
- Draw(B1, 0);
- }
-
- public override void OnBarOpen(Bar bar)
- {
- if (86400 == bar.Size)
- {
- i_reverse = reverse * (bar.Open / 100.0);
- i_rangemin = rangemin * (bar.Open / 100.0);
- div = Math.Max(xdiv, 1);
-
- base.ChangeTradingDay();
- }
- }
-
- public override void OnBar(Bar bar)
- {
- if (86400 == bar.Size)
- {
- //表示今天结束了,要记下今天的开高底收和明天可以用到的价格
- UpdateAtDaily_RBreaker(bar);
- UpdateAtDaily_HighLow(bar);
-
- rfilter = (preDayHigh - preDayLow) >= i_rangemin;
- return;
- }
-
- UpdateAtBar_RBreaker(bar);
- UpdateAtBar_HighLow(bar);
-
- double _S1 = _senter + (HighToday - _ssetup) / div;
- double _B1 = _benter - (_bsetup - LowToday) / div;
-
- S1.Add(bar.DateTime, _S1);
- B1.Add(bar.DateTime, _B1);
-
- do
- {
- // 尾盘平仓
- if (0 != ExitOnClose(60,""))
- break;
-
- if (GetCurrentQty() > 0)
- {
- if ((HighToday > _ssetup && bar.Close < _S1)
- || bar.Close < _sbreak)
- {
- string text = string.Format("{0}>{1}&&{2}<{3}",
- HighToday, _ssetup,
- bar.Close, _S1);
- TargetPosition = -1;
- TextParameter.Text = text;
- }
- }
- else if (GetCurrentQty() < 0)
- {
- if ((LowToday < _bsetup && bar.Close > _B1)
- || bar.Close > _bbreak)
- {
- string text = string.Format("{0}>{1}&&{2}<{3}",
- LowToday, _bsetup,
- bar.Close, _B1);
- TargetPosition = 1;
- TextParameter.Text = text;
- }
- }
- else
- {
- if (bar.Close > _bbreak)
- {
- TargetPosition = 1;
- TextParameter.Text = string.Format("{0}>{1}", bar.Close, _bbreak);
- }
- if (bar.Close < _sbreak)
- {
- TargetPosition = -1;
- TextParameter.Text = string.Format("{0}<{1}", bar.Close, _bbreak);
- }
- }
-
- } while (false);
-
- base.OnBar(bar);
- }
- }
-
-}
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+using OpenQuant.API;
+using OpenQuant.API.Indicators;
+using OpenQuant.API.Plugins;
+using QuantBox.OQ.Demo.Module;
+using QuantBox.OQ.Demo.Helper;
+
+namespace QuantBox.OQ.Demo.Strategys
+{
+ ///
+ /// R-Breaker
+ ///
+ /// 使用方法,添加一个日线,添加一个1分钟线
+ /// 将第一天前一天的收盘、最高、最低填好
+ /// 由于历史的收高低是手工填写的,所以整个代码中没有加载历史数据的代码,
+ /// 如果想长期无人值守,只要在点运行前改正好上一交易日的收高低即可
+ ///
+ /// 网上金字塔版,带图
+ /// http://www.yafco.com/show.php?contentid=261740
+ /// 论坛上的TB版
+ /// http://www.smartquant.cn/forum/forum.php?mod=viewthread&tid=194
+ ///
+ public class RBreaker_code : TargetPositionModule
+ {
+ //第一次运行时,前一天的开高底收
+ [Parameter("前一天最高价", "PreDay")]
+ ///
+ /// 前一天最高价
+ ///
+ double preDayHigh = 0;
+ [Parameter("前一天最低价", "PreDay")]
+ double preDayLow = 0;
+ [Parameter("前一天收盘价", "PreDay")]
+ double preDayClose = 0;
+
+ [OptimizationParameter(0.3, 0.5, 0.05)]
+ [Parameter]
+ double f1 = 0.35;
+ [Parameter]
+ [OptimizationParameter(0.05, 0.09, 0.01)]
+ double f2 = 0.07;
+ [Parameter]
+ [OptimizationParameter(0.10, 0.15, 0.01)]
+ double f3 = 0.12;
+ [Parameter]
+ double Qty = 1;
+
+ double reverse = 0.5;
+ double rangemin = 0.2;
+ double xdiv = 3;
+
+ double div = 3;
+ double i_reverse = 1;
+ double i_rangemin = 1;
+ bool rfilter;
+
+ TimeSeries S1;
+ TimeSeries B1;
+
+ long barSize = long.MaxValue;
+
+ #region R-Breaker
+ TimeSeries ssetup;
+ TimeSeries bsetup;
+ TimeSeries senter;
+ TimeSeries benter;
+ TimeSeries bbreak;
+ TimeSeries sbreak;
+
+ double _ssetup = double.NaN;
+ double _bsetup = double.NaN;
+ double _senter = double.NaN;
+ double _benter = double.NaN;
+ double _bbreak = double.NaN;
+ double _sbreak = double.NaN;
+
+ void UpdateAtDaily_RBreaker(Bar bar)
+ {
+ preDayHigh = bar.High;
+ preDayLow = bar.Low;
+ preDayClose = bar.Close;
+
+ Update6Line();
+ }
+ ///
+ ///
+ ///
+ void Update6Line()
+ {
+ //先计算,时候到了再放到序列中
+ _ssetup = preDayHigh + f1 * (preDayClose - preDayLow);
+ _bsetup = preDayLow - f1 * (preDayHigh - preDayClose);
+
+ _senter = (1 + f2) / 2.0 * (preDayHigh + preDayClose) - f2 * preDayLow;
+ _benter = (1 + f2) / 2.0 * (preDayLow + preDayClose) - f2 * preDayHigh;
+
+ _bbreak = _ssetup + f3 * (_ssetup - _bsetup);
+ _sbreak = _bsetup - f3 * (_ssetup - _bsetup);
+ }
+
+ void UpdateAtBar_RBreaker(Bar bar)
+ {
+ ssetup.Add(bar.DateTime, _ssetup);
+ bsetup.Add(bar.DateTime, _bsetup);
+ senter.Add(bar.DateTime, _senter);
+ benter.Add(bar.DateTime, _benter);
+ bbreak.Add(bar.DateTime, _bbreak);
+ sbreak.Add(bar.DateTime, _sbreak);
+ }
+ #endregion
+
+ #region HighLow
+ double HighToday = double.MinValue;
+ double LowToday = double.MaxValue;
+ void UpdateAtDaily_HighLow(Bar bar)
+ {
+ HighToday = double.MinValue;
+ LowToday = double.MaxValue;
+ }
+ void UpdateAtBar_HighLow(Bar bar)
+ {
+
+ HighToday = Math.Max(HighToday, bar.High);
+ LowToday = Math.Min(LowToday, bar.Low);
+ }
+ #endregion
+
+ public override void OnStrategyStart()
+ {
+ base.OnStrategyStart();
+
+ // 测试用,自定义交易时间,仿真或实盘时可删除
+ base.TimeHelper = new TimeHelper(new int[] { 0, 2400 }, 2100, 1458);
+
+ base.TargetPosition = 0;
+ base.DualPosition.Long.Qty = 0;
+ base.DualPosition.Short.Qty = 0;
+
+ // 自动得到当时时间窗口大小
+ foreach (BarRequest barRequest in DataRequests.BarRequests)
+ {
+ barSize = Math.Min(barSize, barRequest.BarSize);
+ }
+ Console.WriteLine("barSize = {0}", barSize);
+
+ Update6Line();
+
+ ssetup = new TimeSeries("观察卖出价", Color.Green);
+ bsetup = new TimeSeries("观察买入价", Color.Green);
+ bbreak = new TimeSeries("突破买入价", Color.Red);
+ sbreak = new TimeSeries("突破卖出价", Color.Red);
+ senter = new TimeSeries("反转卖出价", Color.Black);
+ benter = new TimeSeries("反转买入价", Color.Black);
+
+ S1 = new TimeSeries("S1", Color.Blue);
+ B1 = new TimeSeries("B1", Color.Blue);
+
+ Draw(ssetup, 0);
+ Draw(bsetup, 0);
+ Draw(bbreak, 0);
+ Draw(sbreak, 0);
+ Draw(senter, 0);
+ Draw(benter, 0);
+
+ Draw(S1, 2);
+ Draw(B1, 2);
+ }
+
+ public override void OnBarOpen(Bar bar)
+ {
+ if (86400 == bar.Size)//当天最后一根K线
+ {
+ i_reverse = reverse * (bar.Open / 100.0);
+ i_rangemin = rangemin * (bar.Open / 100.0);
+ div = Math.Max(xdiv, 1);
+
+ base.ChangeTradingDay();
+ }
+ }
+
+ public override void OnBar(Bar bar)
+ {
+ if (86400 == bar.Size)
+ {
+ //表示今天结束了,要记下今天的开高底收和明天可以用到的价格
+ UpdateAtDaily_RBreaker(bar);
+ UpdateAtDaily_HighLow(bar);
+
+ rfilter = (preDayHigh - preDayLow) >= i_rangemin;
+ return;
+ }
+
+ UpdateAtBar_RBreaker(bar);
+ UpdateAtBar_HighLow(bar);
+
+ double _S1 = _senter + (HighToday - _ssetup) / div;
+ double _B1 = _benter - (_bsetup - LowToday) / div;
+
+ S1.Add(bar.DateTime, _S1);
+ B1.Add(bar.DateTime, _B1);
+
+ do
+ {
+ // 尾盘平仓
+ if (0 != ExitOnClose(60,""))
+ break;
+
+ if (GetCurrentQty() > 0)
+ {
+ if ((HighToday > _ssetup && bar.Close < _S1)
+ || bar.Close < _sbreak)
+ {
+ string text = string.Format("{0}>{1}&&{2}<{3}",
+ HighToday, _ssetup,
+ bar.Close, _S1);
+ TargetPosition = -1;
+ TextParameter.Text = text;
+ }
+ }
+ else if (GetCurrentQty() < 0)
+ {
+ if ((LowToday < _bsetup && bar.Close > _B1)
+ || bar.Close > _bbreak)
+ {
+ string text = string.Format("{0}>{1}&&{2}<{3}",
+ LowToday, _bsetup,
+ bar.Close, _B1);
+ TargetPosition = 1;
+ TextParameter.Text = text;
+ }
+ }
+ else
+ {
+ if (bar.Close > _bbreak)
+ {
+ TargetPosition = 1;
+ TextParameter.Text = string.Format("{0}>{1}", bar.Close, _bbreak);
+ }
+ if (bar.Close < _sbreak)
+ {
+ TargetPosition = -1;
+ TextParameter.Text = string.Format("{0}<{1}", bar.Close, _bbreak);
+ }
+ }
+
+ } while (false);
+
+ base.OnBar(bar);
+ }
+ }
+
+}
diff --git a/Demo/QuantBox.OQ.Demo/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/Demo/QuantBox.OQ.Demo/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
new file mode 100644
index 0000000..a6eb8ce
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ
diff --git a/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.csproj.FileListAbsolute.txt b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.csproj.FileListAbsolute.txt
new file mode 100644
index 0000000..4ea073f
--- /dev/null
+++ b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.csproj.FileListAbsolute.txt
@@ -0,0 +1,5 @@
+D:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.OQ.Demo.dll
+D:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\QuantBox.OQ.Demo.pdb
+D:\用户目录\Documents\GitHub\OpenQuant\Demo\QuantBox.OQ.Demo\obj\Debug\QuantBox.OQ.Demo.csprojResolveAssemblyReference.cache
+D:\用户目录\Documents\GitHub\OpenQuant\Demo\QuantBox.OQ.Demo\obj\Debug\QuantBox.OQ.Demo.dll
+D:\用户目录\Documents\GitHub\OpenQuant\Demo\QuantBox.OQ.Demo\obj\Debug\QuantBox.OQ.Demo.pdb
diff --git a/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.csprojResolveAssemblyReference.cache b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.csprojResolveAssemblyReference.cache
new file mode 100644
index 0000000..e508d73
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.csprojResolveAssemblyReference.cache differ
diff --git a/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.dll b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.dll
new file mode 100644
index 0000000..cd673c1
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.dll differ
diff --git a/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.pdb b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.pdb
new file mode 100644
index 0000000..9531cbc
Binary files /dev/null and b/Demo/QuantBox.OQ.Demo/obj/Debug/QuantBox.OQ.Demo.pdb differ
diff --git a/Extensions/src/QunatBox.OQ.Extensions/QuantBox.OQ.Extensions.csproj b/Extensions/src/QunatBox.OQ.Extensions/QuantBox.OQ.Extensions.csproj
index eda7b9d..ee59040 100644
--- a/Extensions/src/QunatBox.OQ.Extensions/QuantBox.OQ.Extensions.csproj
+++ b/Extensions/src/QunatBox.OQ.Extensions/QuantBox.OQ.Extensions.csproj
@@ -16,7 +16,7 @@
true
full
false
- ..\..\..\..\..\..\..\Program Files %28x86%29\SmartQuant Ltd\OpenQuant\Bin\
+ C:\Program Files %28x86%29\SmartQuant Ltd\OpenQuant\Bin\
DEBUG;TRACE
prompt
4
@@ -30,6 +30,7 @@
4
+
False
..\..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Bin\Newtonsoft.Json.dll
@@ -40,24 +41,24 @@
False
- ..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Data.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Data.dll
False
False
- ..\..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Execution.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Execution.dll
False
- ..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.FIX.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.FIX.dll
False
- ..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Instruments.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Instruments.dll
False
- ..\..\..\..\..\..\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Providers.dll
+ C:\Program Files (x86)\SmartQuant Ltd\OpenQuant\Framework\bin\SmartQuant.Providers.dll
False
@@ -91,6 +92,9 @@
+
+
+
+
\ No newline at end of file